NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: dreamCoder on September 07, 2013, 02:34:42 AM
-
Just want to know if it is even possible to do like this in NASM.
%macro viewreg 1
mov bx, %1
%endmacro
viewreg ax
Thanks
-
Sorry, the problem solved already.
-
Okay... yeah you can do that. A problem, if you call it that, is that if you do "viewreg bx" it'll generate "mov bx, bx". A little "%if" comparison will eliminate it, if you care.
Best,
Frank
-
Thanks for the advice Frank.
-
Hi again Frank. I wrote this macro to display the content of a register
%macro viewreg 1
pusha
jmp %%tab
%%htable db '0123456789ABCDEF'
%%tab:
mov bx, %%htable
mov cx, %1
mov di, 0
mov si, 0
xchg ch, cl
jmp %%main
%%main:
mov dx, cx
and dl, 0x0F0
and cl, 0x0F
shr dl, 4
mov al, dl
xlatb
call %%putc
mov al, cl
xlatb
call %%putc
inc si
cmp si, 2
je %%quit
mov cl, dh
jmp %%main
%%putc:
push ax
mov ah, 0x0e
int 0x10
pop ax
ret
%%quit:
popa
%endmacro
Possible usage:
org 100h
%include 'mac16.mac'
segment .code
mov bx, 3
viewreg bx
call newline
viewreg sp
jmp exit
newline:
mov ah, 0x0e
mov al, 0x0d
int 0x10
mov al, 0x0a
int 0x10
ret
exit:
mov ah, 0
int 0x16
int 0x20
segment .data
nothing db 0
Is it possible to pass the register's name to the macro as well so that we can have a display like
BX=0003
instead of just the content?
Thanks.
-
Well, I dunno. I thought I could do it with just a:
db "%1"
...etc. But this gives me a literal "%1" in my string instead of "bx". There may be a way to do this using "%defstr", but I haven't been able to find it (I am not a sophisticated macro user!). I have managed to do it by using two parameters, one with quotes and one without. This is UGLY!
%macro viewreg 2
[section .data]
%%regname db %1, " = ", 0
__SECT__
pusha
mov si, %%regname
%%topname:
lodsb
cmp al, 0
jz %%endname
call %%putc
jmp %%topname
%%endname:
popa
pusha
jmp %%tab
%%htable db '0123456789ABCDEF'
%%tab:
mov bx, %%htable
mov cx, %2 ; do this before altering bx?
mov di, 0
mov si, 0
xchg ch, cl
jmp %%main
%%main:
mov dx, cx
and dl, 0x0F0
and cl, 0x0F
shr dl, 4
mov al, dl
xlatb
call %%putc
mov al, cl
xlatb
call %%putc
inc si
cmp si, 2
je %%quit
mov cl, dh
jmp %%main
%%putc:
push ax
mov ah, 0x0e
int 0x10
pop ax
ret
%%quit:
popa
%endmacro
org 100h
section .code
mov bx, 3
viewreg "bx", bx
ret
I have not tested this - not in the mood to boot up DOS. It "looks like" it's producing what I had in mind. You can probably fix my errors, if any.
A possible advantage to the "two parameter" macro is that you could do:
viewreg "frooble count", bx
if you wanted to.
Does this work with bx, as you had it? It "looks" to me like it's going to display the address of your hex table, not what was in bx originally. I think you should set up cx with %1 before you alter bx (as per comment). If it produces "mov cx, cx", that's life - won't hurt. If you use it with something other than a 16-bit register (or other appropriate operand for "mov cx, ...") you'll get errors, of course. This is going to produce a lot of "duplicate" code if you use it more than a couple of times. A subroutine (possibly called by a macro), might be more appropriate here. If you don't mind "duplicate" code, no problem.
Best,
Frank
-
thanks for the solution frank. I learned many nasm things from your suggestion.
As for the BX, I moved the instruction after the mov cx, %2 so that cx get the current value of BX instead of the htable Thanks for spotting the bug.
Will post the full once I got it cleaned up.
-
To make the register name a quoted string, use the %defstr directive.
%push
%defstr %$regName %1
db %$regName, 0
%pop
-
Hi Frank and Bryan.
Have been doing translation jobs for my 16-bit hobby macros in other ASM language and I intend to release it in full to NASM board especially for newbies and hobbyists alike. The problem is I can only translate half of it since my knowledge of NASM is very limited, so is my time. Most of the problem lies in the macro parameters that can be taken as tokens.
in *ASM:
macro viewreg reg,base ;2 macro arguments
{
....
if base eq bin ; bin is a token. Not a variable, constant or a string
...
end if
...
}
Called like this:
...
viewreg ax,bin
...
Is there any equivalence in NASM for the %if...%endif part of the code above that evaluate tokens like bin? I need it so that I can extend my macros because for now my macros are pretty basic with only minimum features, unlike the ones I already completed in other language. If you can show me how, then maybe I can apply them to the rest of the pending macros.
This is one example of my half-completed macro. The purpose is to display the content of the register and the options to display multiple base conversions of it (this is my problem so far).
NOTE:putchar,printbin, printdec and prints are another macros
%macro viewreg 2
pusha
mov ax,%1
mov si,4
mov bx,16
xor dx,dx
%if %1 == ax
prints "AX:"
%elif %1 == bx
prints "BX:"
%elif %1 == cx
prints "CX:"
%elif %1 == dx
prints "DX:"
%elif %1 == di
prints "DI:"
%elif %1 == si
prints "SI:"
%elif %1 == bp
prints "BP:"
%elif %1 == sp
prints "SP:"
%elif %1 == cs
prints "CS:"
%elif %1 == ds
prints "DS:"
%elif %1 == es
prints "ES:"
%elif %1 == ss
prints "SS:"
%endif
%%begin:
div bx
push dx
xor dx,dx
dec si
test si,si
jz %%convert
jmp %%begin
%%convert:
inc si
pop ax
add al,30h
cmp al,39h
jle %%display
add al,7
%%display:
putchar al
cmp si,4
je %%exit
jmp %%display
%%exit:
%if %2 == ???? ;this part
printbin %1
%elseif %2 == ???
printdec %1
%endif
popa
%endmacro
Thanks for your patience and time.
-
Hi dreamCoder,
I think you'd want "%ifidn" for this, or "%ifidni" for case-insensitive.
http://www.nasm.us/xdoc/2.11/html/nasmdoc4.html#section-4.4.5
%ifidni %2, bin
;...
That's untested, but I think it should do what you want. (might want quotes around "bin", etc. but I don't think so)
Best,
Frank
-
Thanks Frank. That did solve some of the problem. My next problem is when using the %ifidn in testing multiple cases of %2 like I commented below. It doesn't affect my code. What I want to do with the test is to make sure that if any of the tokens (-o,-b,-d,-s) exist, it takes a slightly different path and should affect the other test down below (that prints their base equivalences). Is this even the correct way to use %ifidn? It however works when I used %ifnidn but the code path will produce incorrect result.
%macro reg 1-3
pusha
%ifidn %2,-o || %2,-d || %2,-b || %2,-s ;PROBLEM
push %1
%endif
mov ax,%1
mov si,4
mov bx,16
xor dx,dx
%if %1 == ax
puts "AX:",-line
%elif %1 == bx
puts "BX:",-line
%elif %1 == cx
puts "CX:",-line
%elif %1 == dx
puts "DX:",-line
%elif %1 == di
puts "DI:",-line
%elif %1 == si
puts "SI:",-line
%elif %1 == bp
puts "BP:",-line
%elif %1 == sp
puts "SP:",-line
%elif %1 == cs
puts "CS:",-line
%elif %1 == ds
puts "DS:",-line
%elif %1 == es
puts "ES:",-line
%elif %1 == ss
puts "SS:",-line
%endif
%%begin:
div bx
push dx
xor dx,dx
dec si
test si,si
jz %%conv
jmp %%begin
%%conv:
inc si
pop ax
add al,30h
cmp al,39h
jle %%disp
add al,7
%%disp:
putchar al
cmp si,4
je %%done
jmp %%conv
%%done:
%ifidn %2,-b || -d || -o || -s ;PROBLEM
putchar ' '
putchar '['
pop %1
%else
jmp %%exit
%endif
%ifidn %2,-b
putbin %1,-line
%elifidn %2,-o
putoct %1,-line
%elifidn %2,-d
putint %1,,-line
%elifidn %2,-s
putint %1,-s,-line
%endif
putchar ']'
%%exit:
%ifnidn %3,-line
line
%endif
popa
%endmacro
Thanks for your responds.
-
The expected output is:
mov cx,35h
reg cx
Displays CX:0035
mov cx,100h
reg cx,-d ;display decimal equivalence
Displays CX:0100 [256]
mov cx,0FFh
reg cx,-b ;display binary equivalence
Displays CX:00FF [0000000011111111]
-
My next problem is when using the %ifidn in testing multiple cases of %2 like I commented below. It doesn't affect my code. What I want to do with the test is to make sure that if any of the tokens (-o,-b,-d,-s) exist, it takes a slightly different path and should affect the other test down below (that prints their base equivalences). Is this even the correct way to use %ifidn?
No, this isn't the correct way to use %ifidn. The %ifidn directive expects two parameters, not an expression. The || stuff is invalid in this case. You should use multiple %[el]ifidn statements.
%ifidn %2,-o
push %1
%elifidn %2,-d
push %1
%elifidn %2,-b
push %1
%elifidn %2,-s
push %1
%endif