flat assembler
Message board for the users of flat assembler.
![]() Goto page 1, 2 Next |
Author |
|
fasmnewbie 26 Aug 2013, 17:58
Edit: Decided not to paste it here. Its too long. Just download the attachment. Below is the list of macros in mac16.inc
Code: ;================= GUIDES ON USAGE ======================; ;-Save this file in the same dir as your source file. ; ;-To use mac16 in your source, use <include> directive. ; ;-Use a macro by typing the name of the macro and ; ; supply parameters if necessary. Read descriptions. ; ;-Strictly 16-bit. No error-checking. All unsigned ; ;-Distribute freely for educational purposes only. ; ;-Use at own risk. NOT for critical systems. Unoptimized.; ;-Use init_ds/es for MZ format, at beginning of code. ; ;-Use for small tasks only. Tends to get larger easily ; ;-Macro names end with X are alternatives ; ;-Use pquit at the end of source to exit properly. ; ;PARAMETERS: ; ;- [db],[dw] = mem variable in square bracket ; ;- db,dw = Variable without bracket ; ;- imm16/8 = Size of immediate (word/byte) ; ;- r16/r8 = 16-bit register / 8-bit register ; ;- * = Parameter required. Else, optional ; ;ERROR MESSAGES: ; ;- '#','<','!','Overflow' (can't remember them all :p) ; ;--------------------------------------------------------; ;================== LIST OF MACROS ======================; ;prtr - Display 16-bit register ;flags - Display Flags register ;flagsX - Alternative to flags ;dumpreg - Dump register ;geto - Get and save Octal string from kboard. ;getb - Get and save Bin string from kboard. ;geth - Get and save Hex string from kboard. ;geti - Get and save Decimal string from kboard ;getc - Get a character from kboard ;gets - Get string from keyboard ;prtc - Display a character to screen ;prts - Print string using 2 sub macros ;prt - Print 0-terminated string var (alt) ;prth - Display Hex string ;prti - Display Decimal string ;prto - Display Oct string ;prtb - Display Bin string (formatted) ;prtbX - Alternative to prtb ;pbin - Display Bin string (raw format) ;conv - Base converter (16-bit) ;convX - Alternative to conv ;bin2dec - Convert true binary to decimal ;goto - Goto cursor position ;bitf - Extract bit field from a word ;bitfX - Alternative to bitf ;pow - 16-bit power function ;cls - Clear 80x25 console screen ;init_ds - Initialize DS ;init_es - Initialize ES ;pause - Pause the screen ;quit - Quit to OS ;pquit - Pause and quit to OS ;line - Print line(s) ;lineX - Alternative to line - Print single line ;tab - Print tab (buggy) ;TOTAL 35 macros + 2 sub macros(prtCStr/prtStr) ; ;============================ ;Recommended Skeleton for COM ;============================ ; org 100h ; include 'mac16.inc' ; <your codes here> ; pquit ; <your data here> ;=========================== ;Recommended Skeleton for MZ ;=========================== ; format mz ; include 'mac16.inc' ; entry start:code ; ; segment start ; code: ; init_ds dseg ; <your codes here> ; pquit ; segment dseg ; <your data here> ; ;start,code,dseg are own identifiers Good luck. Last edited by fasmnewbie on 22 Dec 2013, 16:12; edited 11 times in total |
|||
![]() |
|
fasmnewbie 26 Aug 2013, 18:09
Recommended skeleton for COM
Code: org 100h include 'mac16.inc' ;your codes here pquit ;data definitions here For MZ Code: format mz include 'mac16.inc' entry code:start segment code start: init_ds dataseg init_es xtra ;if you wan to use ES ;codes here pquit segment dataseg ;data goes here segment xtra ;data goes here dataseg and xtra should be any valid identifiers and identifiy to DS / data segment and ES respectively. Last edited by fasmnewbie on 13 Sep 2013, 02:38; edited 1 time in total |
|||
![]() |
|
fasmnewbie 26 Aug 2013, 18:21
Quick note:
Actually I used to have two separate macros each for COM and MZ. It runs fine. But ever since I decided to combine them into a single macro, bugs started appearing once in a while. Help us improve/correct it. Thank you very much for sharing your expertise. |
|||
![]() |
|
fasmnewbie 28 Aug 2013, 08:59
Ok for comparison purpose
This is how you'll see from the internet all the basic steps in printing a string. Code: mov ax, dataseg ;OFFSET dataseg in MASM mov ds, ax mov ah, 9h int 21h You can do that in FASM like this Code: format mz entry start:main segment start main: mov ax, var mov ds, ax ;setup DS mov dx, hello ;setup DX or offset mov ah, 9h ;function ah=9h print a null-terminated string at DS:DX int 21h ;of int 21h ;pause the screen mov ah, 0h int 16h ;exit to command mov ah, 4ch int 21h segment var hello db 'Hello World$' In FASM's COM format Code: org 100h ;No need to setup DS since DS assumed to be = CS ;Flat memory mode (tiny) mov dx, hello ;save the address of hello into DX mov ah, 9h int 21h ;pause the screen mov ah, 0h int 16h ;exit to command mov ah, 4ch int 21h hello db 'Hello World$' But for the macro I included here, I use the BIOS int 10h (function ah=0eh) interrupt rather than DOS's int 21h interrupt. Macro prtc is used to print a character one at a time but I loop it to print a series of character. prtc is based on int 10h. This is how to do it using the int 10h. Code: org 100h mov si, 0 mov ah, 0eh ;funtion ah=0eh for int 10h .prt: mov al, [hello+si] ;The char to print cmp al, '$' je .quit int 10h inc si jmp .prt .quit: ;Pause mov ah, 0h int 16h ;Exit to DOS mov ah, 4ch int 21h hello db 'Hello World!$' By using the macro prts, you can achieve the same purpose because it is based on prtc macro, which turn out to be a repetitive call to int 10h. Basically the same thing. It is like calling a reusable function in C/C++. Code: org 100h include 'mac16.inc' ;must include this if u want to use the attached macros prts "Hello World" prts hello pquit ;macro for pause and exit to DOS hello db 'Hello World',0 For MZ Code: format mz include 'mac16.inc' entry start:main segment start main: init_ds var prts 'Hello WORLD' prts hello pquit segment var hello db 'Hello World',0 So to cut it short, assembly language programming is not that difficult and I hope you can accelerate your learning by using simple macros provided here. Cheers and good luck. Last edited by fasmnewbie on 13 Sep 2013, 02:56; edited 1 time in total |
|||
![]() |
|
fasmnewbie 31 Aug 2013, 12:17
For those asking how to implement geti macro without using the macro... this is the macro-less version for both geti and prti combined, plus some conversion modules.
Code: ;PROGRAM TO READ INTEGER FROM KEYBOARD ;DISPLAY IT BY THE SELECTED BASE org 100h pusha mov si, 0 mov [temp],0 .get: ;e.g 2134 mov ah, 0 int 16h ;Get the digits call .prtc cmp al, 0dh ;if ENTER je .ok cmp al, 40h ;if invalid digit jge .quit sub al, 30h ;To ASCII (0-9) mov byte[a+si], al ;Split: one digit, one byte inc si ;next byte/digit jmp .get .ok: call .line num=0 mov bp, si ;save si. cmp si, 1 ;if single digit je .final cmp si, 2 ;if double digit je .prev mov cx, si ;Used for outer loop sub cx, 2 ;ignore the last two digits xor ax, ax push num ;PROCESSING MODULE: Convert string to number-------- .toNum: mov di, si ;For power loop sub di, 2 ;off-by-one adjustment mov ax, 10 ;for MUL mov bx, 10 ;for MUL .pow: mul bx ;power projection for each digit cmp di, 1 ;e.g 2134 -> 1000, 10*10*10 je .acc ;Answer in AX (03e8h or 1000) dec di jmp .pow .acc: pop di ;this is num xor bx, bx mov bl, byte [a+di] ;Digit 2 mul bx ;Digit 2 * AX (1000) add [temp], ax ;Accumulate to temp inc di push di ;save for addressing dec cx cmp cx, 0 ;Check outer loop je .prev dec si jmp .toNum ;loop to next digit .prev: ;For second last digit mov si, bp ;load original si mov ax, 10 mov bl, byte[a+si-2] ;Digit 3 mul bx ;Digit 3 * AX (10) add [temp], ax ;accumulate to variable .final: mov al, byte [a+si-1] ;Digit 4 add byte [temp], al ;Accumulate to variable jmp .done ;------------------------------------------------- .done: push [temp] pop [a] ;a now keeps true integer jmp .select ;SELECT ONE MODULE HERE .select: xor dx, dx ;4 ops common to all modules xor si, si xor ax, ax mov ax, [temp] ;jmp .toOCT ;jmp .toINT ;jmp .toHEX jmp .toBIN ;jmp .quit ;CONVERT AND PRINT INT MODULE ================= .toINT: mov bx, 10 ;Base 10 .convert2Int: div bx mov byte [mys+si], dl xor dx, dx inc si cmp ax, 0 je .prtint jmp .convert2Int .prtint: dec si add byte [mys+si], 30h mov al, byte [mys+si] call .prtc cmp si, 0 je .quit jmp .prtint ;============================================== ;CONVERT AND PRINT OCTAL MODULE================ .toOCT: mov bx, 8 ;Base 8 .convert2Oct: div bx mov byte [mys+si], dl xor dx, dx inc si cmp ax, 0 je .prtoct jmp .convert2Oct .prtoct: dec si add byte [mys+si], 30h mov al, byte [mys+si] call .prtc cmp si, 0 je .quit jmp .prtoct ;============================================== ;CONVERT AND PRINT HEX MODULE================== .toHEX: mov bx, 16 ;Base 16 .convert2Hex: div bx mov byte [mys+si], dl xor dx, dx ;Must clear b4 next DIV inc si cmp ax, 0 je .prthex jmp .convert2Hex .prthex: dec si add byte [mys+si], 30h cmp [mys+si], 39h jle .go2 add byte [mys+si], 7 .go2: mov al, byte [mys+si] call .prtc cmp si, 0 je .quit jmp .prthex ;============================================== ;CONVERT AND PRINT BIN MODULE================== .toBIN: mov bx, 2 .convert2Bin: div bx mov byte [mys+si], dl xor dx, dx inc si cmp ax, 0 je .prtbin jmp .convert2Bin .prtbin: dec si cmp byte [mys+si], 1 jne .zero .one: mov byte [mys+si], '1' jmp .go4 .zero: mov byte [mys+si], '0' .go4: mov al,byte [mys+si] call .prtc cmp si,0 je .quit cmp si,1+(31 mod 8) ;Separate 8-bits jz .part jmp .prtbin .part: mov al,' ' call .prtc jmp .prtbin ;============================================== .line: push ax mov ax, 0e0dh int 10h mov ax, 0e0ah int 10h pop ax ret .prtc: mov ah, 0eh int 10h ret .quit: popa mov ah,0 int 16h int 20h temp dw ? a dw ? mys db 31 dup('0') You can select any of the conversion base by uncommenting any of the jmp instructions found at the [.select] label. This is another one for both combined gets and prts without macros. Code: ;PROGRAM: To get string from keyboard ; : Store it in a string variable ; : Then print the string to screen org 100h pusha ;save all general registers mov si,0 ;index to string. Must preserve this .get: ;Get a character mov ah,0 ;using int 16h, function AH=0 int 16h ;AL=char call .prtc ;echo what you entered (AL) cmp al,0dh ;if ENTER, means done input je .done mov byte[string+si],al ;save that char in var inc si ;si = si + 1 jmp .get ;loop to get next char .done: call .line ;print a new line mov di,0 ;counter xor ax,ax ;prepare ax for other operations jmp .prts .prts: mov al,byte[string+di] call .prtc ;print the char inc di ;add loop counter cmp di,si ;compare against current index (si) je .quit ;if end of text, quit jmp .prts ;loop to next char .line: ;prints new line mov ah,0eh ;using int 10h, function ah=0eh mov al,0dh int 10h mov al,0ah int 10h ret .prtc: ;prints a character in AL mov ah,0eh ;using int 10h, function ah=0eh int 10h ret .quit: popa ;restore all general registers mov ah,0h ;Pause the screen int 16h ;or wait for any key before int 20h ;return to system string db 50 These programs can be further improved though. Hope you can learn many things from this. Cheers and have a good weekend. |
|||
![]() |
|
fasmnewbie 31 Aug 2013, 16:06
Slight changes to the attached prtr macro
Reason: DS=CS in MZ format where they should be different. Code: ;refer to attachment Last edited by fasmnewbie on 07 Sep 2013, 00:45; edited 1 time in total |
|||
![]() |
|
fasmnewbie 01 Sep 2013, 05:17
Question: I don't see any macro to print/convert from binary to decimal??
Code: prti 1011101b conv 1011101b, -d Enjoy ![]() |
|||
![]() |
|
fasmnewbie 03 Sep 2013, 03:45
I have updated the macro file. You can discard the old one.
I added two new macros last night: 1. bitf ;to extract bitfield from a given word data 2. CPU;get the name of CPU I still can't fix the prts macro though. My advice for now is to avoid using both constant string and a string variable at the same time. Hope somebody can help me fixing it. Ok that's it folks. I can't give any more macros as it will beat the purpose of this learning tool. You can now easily develop your own programs like generating random numbers by using / extending these macros here. I have to quit my programming hobby for now due to work commitment. Learn and practice from the source, and once you get the hang of it, do move on to 32-bit assembly. Good luck and happy programming. |
|||
![]() |
|
DOS386 10 Sep 2013, 09:10
COOOOOOOOOOOOOOOOOOOOOOOOOOOOOL (untested)
|
|||
![]() |
|
fasmnewbie 13 Sep 2013, 02:42
I have attached the latest mac.16 in the first post and pasted it in the second post for my final contribution. Thank you.
|
|||
![]() |
|
fasmnewbie 13 Sep 2013, 02:47
DOS386 wrote: COOOOOOOOOOOOOOOOOOOOOOOOOOOOOL (untested) |
|||
![]() |
|
fasmnewbie 29 Oct 2013, 15:43
I have updated the new mac16.inc.
Date updated 29th Oct 2013 to fix two bugs found: 1. prtr. Display register. CX and SI were not displayed correctly. Fixed 2. geti. Get integer from keyboard. Returned 0 if 256 is entered. Fixed Sorry for the stupid bugs ![]() |
|||
![]() |
|
fasmnewbie 08 Dec 2013, 19:13
I have updated the macro file (Dec 9th, 2013), adding some more macros and fixing some bugs. Still clueless about the macro "prts"
![]() ====== LIST OF MACROS ======= prtr - Display 16-bit register flags - Display Flags register dumpreg - Dump register geto - Get Octal string from kboard. Save value getb - Get Bin string from kboard. Save value geth - Get Hex string from kboard. Save value geti - Get Decimal string from kboard getc - Get a character from kboard gets - Get string from keyboard prtc - Display a character to screen prts - Print String, plus 2 sub macros (buggy) prt - Print 0-terminated string variable. Just a simple alternative prth - Display Hexadecimal string prti - Display Decimal string prto - Display Octal string prtb - Display Binary string conv - Base converter (16-bit) for octal, binary, hex and decimal bin2dec - Convert real binary to decimal string bitf - Extract bit field from a word pow - 16-bit power function cls - Clear 80x25 console screen init_ds - Initialize DS (for MZ format) init_es - Initialize ES (for MZ format) pause - Pause the screen quit - Quit to OS pquit - Pause and quit to OS line - Print new line tab - Print tab (buggy) TOTAL 28 macros + 2 sub macros(prtCStr/prtStr) See latest attachment (Dec 9th, 2013) in the first post. |
|||
![]() |
|
fasmnewbie 10 Dec 2013, 04:52
This is a sample working program demonstrating the use of multiple macros in MZ segmented format.
Code: format mz include 'mac16.inc' entry code:start segment code start: init_ds dseg ;From mac16. Required in MZ prts header line 2 ;Prints 2 empty line begin: prts "Enter an octal(no suffix): ",-line geto myd ;Get 16-bit octal from k/board mov bx,2 ;times 2 mov ax,[myd] ;copy to ax mul bx ;ax = ax * bx jo ovflow ;jump if overflow prtr AX,,,-o ;confirm the value in AX mov word[myd],ax ;copy result back to myd prts `myd, -line ;symbol ` is FASM-specific prts " x 2 = ",-line prto [myd] ;Display the result call ask ;a procedure call jmp begin ;repeat ovflow: prts "Overflow" flags ;verify overflow is set done: prts "DONE." pquit ;A procedure/function ask: prts "Repeat? ('n' to quit): ",-line getc ans ;Get char answer from k/board cmp byte[ans],'n' ;if 'n', exit je done ;cls ;Clears 80*25 console screen line ret ;return to caller segment dseg ;Data segment init above ans db ? ;two data myd dw ? header db "OCTAL INTERACTIVE PROGRAM.",0 Output should be like this Code: OCTAL INTERACTIVE PROGRAM. Enter an octal(no suffix): 7632 AX:1F34 [17464o] myd x 2 = 17464o Repeat? ('n' to quit): y Enter an octal(no suffix): 59<non-octal> AX:0000 [0o] myd x 2 = 0o Repeat? ('n' to quit): y Enter an octal(no suffix): 10 AX:0010 [20o] myd x 2 = 20o Repeat? ('n' to quit): y Enter an octal(no suffix): 177777 Overflow ----OD--SZ-A-P-C 0011101000010011 DONE. |
|||
![]() |
|
fasmnewbie 22 Dec 2013, 16:09
Ok, after some robust tests, this macro file is finally bug-free for the first time this year! LOL LOL
![]() I also fixed that buggy prts macro, hidden bug in geti macro, restructured the memory for some macros, and added a few alternative macros (ending with X) just for reference. Last updated Dec 22nd, 2013. Hope you can benefit from it and finally my "buggy" soul can rest in peace LOOOOOLL. Merry Christmas and Happy New Year. |
|||
![]() |
|
fasmnewbie 23 Dec 2013, 21:27
Final Update, Dec 24th, 2013, with signed integer handling, slight enhancement to bitf, geti macros and other small things I can't remember. Good luck.
|
|||
![]() |
|
fasmnewbie 28 Dec 2013, 16:16
lib16 is a different version of the macro file that I wrote independently of mac16. This one is more compact, partly optimized, with more focus on stack usage rather than index addressing for basic input / output data processing. It offers the same functionalities and shares the same macro names as mac16.
It lacks internal documentation though, but all descriptions in mac16 apply to lib16 as well. Due to time limitations, I haven’t been able to completely test them all. But I hope you’ll find no more bugs. Use them at will to facilitate speedy entrance to FASM and assembly learning. Happy New Year. |
|||
![]() |
|
fasmnewbie 01 Jan 2014, 02:17
Last and Final update on lib16.inc, Jan 1st, 2014. Fixed a small bug and added a few utility macros.
|
|||
![]() |
|
fasmnewbie 08 Jan 2014, 17:01
I just uploaded the 32-bit version of the macro file named lib32.inc along with the minor updates to lib16.inc.
lib32.inc is translated directly from lib16.inc and should be usable under PE console format. A few notes: 1. C's getchar (getchar macro) behaves differently than the 16-bit version. So expect some of the input validity tests to be ineffective. 2. Due to section restrictions of windows, I decided to take out all macros local data and replaced them with something else (except in prts macro and sub macros) 3. For import section, just insert the .idata at the end of the source and nothing else should be added to it. Recommended Skeleton Code: ;============================ ;Recommended Skeleton for PE ;============================ format PE console include 'win32axp.inc include 'lib32.inc' entry main .code main: ;<your codes here> pquit .data ;<your data here> .idata ;<nothing should be added here> No restrictions on usage and I hope it is bug-free. |
|||
![]() |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.