flat assembler
Message board for the users of flat assembler.
![]() Goto page 1, 2 Next |
Author |
|
fasmnewbie 05 May 2014, 20:15
Hi.
This starter pack is intended for newbies, hobbyists and entry-level assembly programmers who want to have a quick entry to FASM programming in DOS environment (MZ, COM and PE format). The zip file contain mac16.inc and mac32.inc for 16-bit and 32-bit DOS programming respectively. The 3rd file is a NOTES.txt explaining in details. These files must reside in the same folder/directory as your source file. This starter pack offers invaluable visual tool that is very much needed by new comers - to see and prove quickly the effect of your codes. They contain various macro routines with primary aim is to TEST, PROBE and VERIFY your codes or other dos-based FASM source codes. In a way, it enables you to debug your code on-the-fly without relying on external debugger. The macros should be used as a tool, and not as a permanent code in your source. They can be inserted at almost every point of your code or use them independently as a quick learning/assesment tool. It is very easy to use and resembles calling any external functions. All you have to do is to include the intended macro file by using the include directive and call any macros inside it. For example, if you want to check the content of the register, you can use the prtreg macro (along with its handy switches if you wish to). Code: format PE console include 'mac32.inc' mov eax,210h prtreg eax ;display plain EAX register prtreg eax,-d ;display EAX with decimal (-d) switch exitp ;pause and exit. Must include everytime to exit properly .msimport ; import library. Must include everytime for PE (flat) Output Code: eax:00000210 eax:00000210 [528] You can then delete or comment out the macro calls once you can confirm that the correct value is loaded into the EAX register. Another sample use - say you want to prove and display the effect of BTC (bit test and complement) instruction against a value in ax, instead of playing the wasting guessing game like this; Code: org 100h mov ax,11010001b btc ax,7 exitp You can include the macro file (mac16.inc for 16-bit ORG) like this and use a combination of tool to help you see the effect the BTC instruction; Code: org 100h include 'mac16.inc' mov ax,11010001b prtreg ax,-b ;verify the content, with -b (binary switch) btc ax,7 ;the instruction you want to learn prtstr "btc ax,7\n" ;a string for output documentation prtreg ax,-b ;see the effect to the bit. exitp Which yields the following visual and helpful output; Code: ax:00D1 [00000000 11010001] btc ax,7 ax:0051 [00000000 01010001] And again, once you have proven the desired effect, you can comment them out or delete the macro calls. Notes: To properly call each macro and their valid switches and parameters, just go to the macro header you want to use. Macro headers explain how to use them. There are also other documentations in each macro files. Hope you like it and can learn fast by using this starter pack. EDIT: June 1st, 2014 new attachment and final update
Last edited by fasmnewbie on 01 Jun 2014, 10:21; edited 1 time in total |
|||||||||||
![]() |
|
fasmnewbie 05 May 2014, 20:38
LIST OF MACROS
Code: ============== LIST OF MACROS =============; prtreg - Display register prtreg8 - Display byte register (AL,AH...DL,DH) locate - Display offset position of a var or label pc - Get current IP flags - Display Flags register opsize - Display size of an instruction or instructions str2dec - Convert string to decimal getint - Get number from kboard with lowercase suffix getdec - Get and save decimal from kboard prtdec - Display Decimal string getoct - Get and save Octal string from kboard. prtoct - Display Oct string getbin - Get and save Bin string from kboard. prtbin - Display Bin string (formatted) pbin - Display Bin string (raw format) gethex - Get and save Hex string from kboard. prthex - Display Hex string getchr - Get a character from kboard and put in var prtchr - Display a character to screen getch - Get character from kboard and put in AL getstr - Get string from keyboard prtstr+2 - Print string using 2 sub macros fprint+2 - printf emulation using 2 sub macros prtbdec - Display integer string of a byte prtboct - Display octal string of a byte prtbhex - Display hex string of a byte prtbbin - Display binary string of a byte line - Print single line lines - Print line(s) conv - Base converter (16-bit) to common bases convert - Alternative to conv bconv - Convert from common bases to up to Base 32 bitf - Extract bit field from a word,with copy pow - 16-bit power function delay - Delay timer rndigit - Get a random decimal digit between 0 to 9 exitp - Pause and quit to OS pause - Pause the screen quit - Quit to OS dumpreg - Dump register movp - Move and push str - String data type struc cmpe - cmp for equal and jump cmpz - cmp for zero and jump cmpne - cmp for not equal and jump dispmem - Small and efficient debugger by l_inc. Found in mac16.inc only preg - For use with Dumpreg. Display register. dsinit - Initialize DS esinit - Initialize ES cls - Clear 80x25 console screen goto - Goto cursor position asc_hex - Display ascii value (hex) asc_dec - Display ascii value (decimal) asc_tab - Print raw ascii table keyb - print keyboard scan code and ascii time - Display BIOS time date - Display BIOS date proc16 - Required for 16 bit procs (from LocoDelAssembly) Found in mac32.inc only prtregl - Display lower 32-bit register prtregh - Display upper 32-bit register getf - Get a double precision value from kboard prtf - Display a precision value .msimport- For importing libraries in flat PE .idata - For importing libraries in PE with sections You can refer to each macro headers on how to use and call them (including the parameters (required of optional) and other switches. Last edited by fasmnewbie on 01 Jun 2014, 10:34; edited 1 time in total |
|||
![]() |
|
fasmnewbie 05 May 2014, 20:55
There is also the proc versions for these macro files offering similar functionality but I decided not to release them because that could provide direct 'answers' to most common assignment/homework questions typically produced by instructors. I am not that cheap ;D
|
|||
![]() |
|
fasmnewbie 05 May 2014, 21:14
Q&A
1. Question: I don't see any use of MS-DOS interrupt routines as per assignment requirements. Your macro file should include them! Answer: Yes they don't. This macro pack helps you with coding verification, but won't provide you direct answers. Use this pack in parallel with whatever you are trying to solve (like displaying string/character using DOS's int 21h). The macros should be able to GREATLY help you all the way to the finish line, but will not be compatible with your assignment requirement. Maybe you get lucky with the 32-bit version. |
|||
![]() |
|
fasmnewbie 05 May 2014, 21:42
Lets take an example code (slightly modified) from ASMGuru62 in other thread and see how you can use this macro file to understand some crucial part of the code. This is the code;
Code: OFFSET equ org 100h use16 MOV DX, OFFSET PRINT0 MOV AH,09H INT 21H MOV DX, OFFSET NEWLINE MOV AH,09H INT 21H PR1: MOV DX, OFFSET PRINT1 MOV AH,09H INT 21H MOV AH,0AH MOV DX, OFFSET INMAX1 INT 21H CMP [INLEN1], 1 JNE PR2 ERR1: MOV DX, OFFSET NEWLINE MOV AH,09H INT 21H MOV DX, OFFSET ERROR1 MOV AH,09H INT 21H MOV DX, OFFSET NEWLINE MOV AH,09H INT 21H JMP PR1 PR2: MOV DX, OFFSET NEWLINE MOV AH,09H INT 21H MOV DX, OFFSET PRINT2 MOV AH,09H INT 21H MOV AH,1 INT 21H MOV [CHAR], AL MOV DX, OFFSET NEWLINE MOV AH,09H INT 21H MOV SI, STRING MOV AL, [CHAR] XOR AH, AH FIND: MOV BH, [SI] INC SI CMP BH, AL JNE NEXT_CHAR INC AH NEXT_CHAR: CMP BH, 0DH JE NR_AP JMP FIND NR_AP: PUSH AX MOV DX, OFFSET COUNT MOV AH,09H INT 21H POP AX CMP AH, 0 JE PRINT_ZERO SHR AX, 8 MOV DX, 0 MOV CX, 10 DIV CX PUSH DX ADD AL, '0' MOV DL, AL MOV AH, 2 CMP AL, '0' JE SKIP INT 21H SKIP: POP DX ADD DL, '0' INT 21H JMP EXIT_NR PRINT_ZERO: MOV DX, OFFSET PRINTZ MOV AH,09H INT 21H EXIT_NR: MOV DX, OFFSET EXITNR MOV AH,09H INT 21H EXIT: MOV AH,1 INT 21H MOV AH,4CH INT 21H NEWLINE DB 10,13,"$" INMAX1 DB 21 INLEN1 DB 0 STRING DB 21 DUP(20H) CHAR DB 0 PRINT0 DB "Input:$" PRINT1 DB "String: $" PRINT2 DB "Character: $" PRINTZ DB "0 $" ERROR1 DB "Error! Enter a string. $" COUNT DB "Output: $" EXITNR DB "$" Output Code: Input: String: asmguru Character: u Output: 2 Now we try to insert a macro to see the happening to BH register in every loop at FIND label. Code: include 'mac16.inc' ;include this to call prtreg OFFSET equ org 100h use16 MOV DX, OFFSET PRINT0 MOV AH,09H INT 21H MOV DX, OFFSET NEWLINE MOV AH,09H INT 21H ; ..... ;cut FIND: MOV BH, [SI] prtreg BX ;debugged line using prtreg to confirm BH at every loop INC SI CMP BH, AL JNE NEXT_CHAR INC AH NEXT_CHAR: CMP BH, 0DH ;0dh found in BH. End of loop. JE NR_AP JMP FIND ;..... cut This is the output, displaying and confirming of BH in every loop until it meets the character '0dh' to exit the loop. Output Code: Input: String: asmguru Character: u BX:6100 BX:7300 BX:6D00 BX:6700 BX:7500 BX:7200 BX:7500 BX:0D00 ;cmp bh,0dh found here. Output: 2 See that how BH register contains all the character previously entered (61h - 'a', '73h - 's' etc). Now you can also do the same at various insertion point to fully understand what this coder is trying to do. |
|||
![]() |
|
AsmGuru62 06 May 2014, 03:40
It is good work, but seems like a lot of effort just to see a register.
But if you'll teach how to use a debugger - it will be better, I think. I always wonder why debugger is never taught in coding courses. |
|||
![]() |
|
fasmnewbie 06 May 2014, 03:55
The use of this starter pack depends on your creativity and effort. For example, you can extend the prtint macro to calculate the size of an instruction or group of instructions between two labels. This way, you would become aware of the size of any instruction you are using or even for the whole source. Could be something like this;
Code: macro opsize a,b { if a-b < 0 prtint b-a,,-line else prtint a-b,,-line end if } In practical use... Code: format PE console include 'mac32.inc' opsize foo,bar foo: mov eax,dword[x] ;the size of this instruction is... 5 bytes bar: exitp x dd 34h .msimport Or if you are 'crazy' enough, you can even calculate the size of the entire import table... something like this; Code: format PE console include 'mac32.inc' opsize foo,bar ;either way is possible mov eax,dword[x] exitp x dd 34h bar: .msimport foo: Which yields the result of 111 bytes. The results may vary by the way ;D |
|||
![]() |
|
fasmnewbie 06 May 2014, 04:14
AsmGuru62 wrote: It is good work, but seems like a lot of effort just to see a register. |
|||
![]() |
|
fasmnewbie 06 May 2014, 04:47
Well, what do you know...
![]() The size of the imported printf function is only 15 bytes (without the string of course). That's some nasty programming in there. Now who says C/C++ is bloated? Code: format PE console include 'mac32.inc' bar: cinvoke printf,"" ;only 15 bytes, no strings attached! foo: opsize foo,bar exitp .msimport Output Code: 15 |
|||
![]() |
|
fasmnewbie 08 May 2014, 01:23
In each macro file, there is one macro called dispmem courtesy of l_inc. This super cool macro is actually an internal debugger. I really didn't expect something like that could be produced solely by using FASM's macro language. You need to compile it at the prompt (not from FASMW) if you want to see the output.
One example is this code (see how dispmem is called); Code: org 100h include 'mac16.inc' dispmem_ xor ax,ax mov al,-4 prtreg ax,-b cbw prtreg ax,-b _dispmem exitp x db -4 That translates to this listing at the prompt once compiled (don't execute it) Code: This maybe too much for the intended users of this starter pack, but once understood, you'll appreciate it. This works for both 16 bit and 32-bit codes. |
|||
![]() |
|
fasmnewbie 08 May 2014, 01:57
The advantage of this macro set (or something similar or better) are;
1. It allows newbies (at least at early level) to code-and-debug at the same time without having to resort to external debugger. In the end, with correct use, they can make sure that all the registers, memory and variables behave as they should at any point of insertion or in any given loop. 2. Instead of 'linking', this starter pack works by 'embedding' to the source code of yours or any other FASM source you are interesting in checking/investigating. Once done, not a single byte is committed to the original source. Macro calls can then be conveniently deleted or commented out without changing the structure or style of the original source. 3. Some of the features offered by these macros are not available in 3rd party debuggers. I am not saying this pack is better, but the features I included here are specifically tailored for noobs like myself that demands straight and simple answers from the 'machine'. Plus, information presented by the debuggers are too overwhelming and intended for much more advanced users. But OllyDbg is good though. Only that you'll have to go out of your coding task and use Olly just to confirm what's in the register (I don't know if I get this right, tried OllyDbg just recently) I am not saying that this starter pack is good. Nope. I know most of the codes in there are naive (and buggy too!). But as long as they work and can help people learn fast, that would be good enough for me, until some better programmers can come up with something better. Anyway, FASM all the way! ![]() |
|||
![]() |
|
fasmnewbie 08 May 2014, 02:25
For using PROC, the safest layout (for COM and PE) is to place all your procedures after the data declarations.
For COM Code: org 100h include 'mac16.inc' ;codes exitp ;data ;your procs here.. like proc prtreg, info mov ax,[info] ;other codes ret endp For PE Code: format pe console include 'mac32.inc' ;sample call stdcall prtreg,ebx ;other codes exitp ;data ;your procs here.. like proc prtreg, info mov eax,[info] ;other codes ret endp ;other procs .msimport For MZ, place the data segment at top Code: format mz include 'mac16.inc' entry main:begin segment dataseg ;your data segment main begin: dsinit dataseg ;codes exitp ;Your procs here To call for any procs you created, you can either use "stdcall" or "call" by observing the way arguments are pushed. Read the FASM manual. For example, calling the "prtax" procedure; Code: ;Calling procedures stdcall prtax,ax,0 ;... ;or push 0 push ax call prtax ;exitp... ;data definitions... ;The procedure definition: 2 parameters proc prtax,info,line ;codes ret endp |
|||
![]() |
|
revolution 08 May 2014, 02:30
fasmnewbie wrote: For using PROC, the safest layout (for COM and PE) is to place all your procedures after the data declarations. |
|||
![]() |
|
fasmnewbie 08 May 2014, 02:42
revolution wrote:
|
|||
![]() |
|
badc0de02 09 May 2014, 21:30
every time these macros that sucks
why doesnt you make a procedure |
|||
![]() |
|
fasmnewbie 10 May 2014, 00:54
badc0de02 wrote: every time these macros that sucks |
|||
![]() |
|
fasmnewbie 15 May 2014, 03:04
bitf macro might look a bit complicated to use. But is as easy as using other macros. I wrote it specifically for CPUID instruction but it's good for other usage as well. The purpose is to extract a bit pattern from any bit positions with the options to copy the extracted bits to a variable, plus you might also want to shift the bits back to normal bit positional values.
Sample usage: Code: org 100h include 'mac16.inc' mov ax,5436h prtreg AX,-b bitf ax,10,5 ;Extract bit 5 to bit 10 from AX register exitp Output Code: AX:5436 [01010100_00110110] 100001 ;bit 10 -> bit 5 extracted Later if you want to copy this extracted information, you can use another variable like this; Code: org 100h include 'mac16.inc' mov ax,5436h prtreg AX,-b bitf ax,10,5,[y] ;Extract bit 5 to bit 10 from AX register. Copy to y prtbin [y] ;prove it exitp y dw ? Output Code: AX:5436 [01010100_00110110] 100001 00000100_00100000 ;content of y But probably you also want to shift the extracted bits back to normal bit positions. In that case you can use the -s switch Code: org 100h include 'mac16.inc' mov ax,5436h prtreg AX,-b bitf ax,10,5,[y],-s ;Copy to y and shift prtbin [y] ;prove it exitp y dw ? Output Code: AX:5436 [01010100_00110110] 100001 00000000_00100001 ;See the bits shifted in y For larger data, you can use index addressing, plus size qualifier but the bit positions should never exceed 15 maximum Code: bitf word[x+2],15,0 ;extract whole word from third byte of y ;given x dd 457767678 Output Code: AX:1B48 [00011011_01001000] 0001101101001000 |
|||
![]() |
|
fasmnewbie 15 May 2014, 03:34
You can add these three basic and and straightforward file processing macros to the existing macro file.
Just simple tasks to create a new file, open for reading and open for writing. Code: ;----------------------------------- ;Create new file (rewrite) ;a = file address ; = filename string must be 0-ended ;----------------------------------- macro fnew@ a { mov ah,3ch mov cl,0 mov dx,a int 21h } ;----------------------------------- ;Open and write file ;a = The file address to open and write ;b = number of bytes to write ;c = address of data source to write ;----------------------------------- macro fopenw@ a,b,c { mov dx,a ;file to open mov al,2 ;read and write mov ah,3dh ;Function to open file int 21h ;Open file. File handle in AX mov bx,ax ;file handle of a mov cx,b ;number of bytes to write mov dx,c ;address of data to copy from mov ah,40h ;write function int 21h ;Write to file mov ah,3eh ;release handle int 21h } ;----------------------------------- ;Open and read a file ;a filename address and 0-ended string ;b number of bytes to read ;c address data buffer to keep whats read ;----------------------------------- macro fopenr@ a,b,c { mov dx,a ;file to open mov al,0 ;read mov ah,3dh ;Function to open file int 21h ;Open file. File handle in AX mov bx,ax ;file handle of a mov cx,b ;number of bytes to read mov dx,c ;buffer of data to keep the bytes mov ah,3fh ;function to read int 21h ;Read file mov ah,3eh ;close handle int 21h } Below is a demo usage on how to create a new assembly source file from within a source file. Code: org 100h include 'mac16.inc' fnew@ newf fopenw@ newf,59,buff ;copy 59 bytes from buff and write to newfile exitp newf db "newfile.asm",0 buff db "org 100h",0dh,0ah,\ ;10 "include 'mac16.inc'",0dh,0ah,\ ;20 "mov ax,255",0dh,0ah,\ ;12 "prtoct ax",0dh,0ah,\ ;11 "exitp",0 ;6 After compiling there should be a newly spawned assembly file, called "newfile.asm" ready to be compiled in your current folder. |
|||
![]() |
|
freecrac 15 May 2014, 05:38
Hello.
I am not sure if some macros exist for the following software interrupts: Quote: --------D-210E------------------------------- Quote: --------D-2119------------------------------- Quote: --------D-2139------------------------------- Quote: --------D-213A------------------------------- Quote: --------D-213B------------------------------- Quote: --------D-2147------------------------------- Quote: --------D-2141------------------------------- Quote: --------D-214300----------------------------- Quote: --------D-214301----------------------------- |
|||
![]() |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.