Reputation: 57
I am trying to create a macro that will print a decimal number for me. My idea was to divide the number by ten, convert the remainder to ASCII and push it into the stack until the the ratio is 0. I then print the digits one by one but for some reason I get a 'Segmentation fault'.
I am using Linux, nasm, and a x86_64 processor.
%macro printInt 1
mov rax, %1
mov rbx, 0
%%loop1: ;Convert all digits to ascii
inc rbx ;Count of the digits in number
mov rdx, 0
div rax
add rdx, 48 ;Convert remainder to ascii
push rdx ;Push remainder into stack
cmp rax, 0 ;Compare ratio to 0
jne %%loop1
%%loop2: ;Print the number digit by digit
dec rbx
mov rax, 1 ;Sys_Write
mov rdi, 1 ;STDOUT
pop rsi ;Pop digit
mov rdx, 1
syscall
cmp rbx, 0
jne %%loop2
%endmacro
section .data
number1 db 123
section .text
global _start
_start:
printInt number1
mov rax, 60
mov rdi, 0
syscall
Any help is appreciated, thanks in advance!
Upvotes: 1
Views: 238
Reputation: 14409
First mistake:
number1 db 123
number1 is defined as BYTE, but will be treated as QUADWORD (mov rax, %1
). Change it to
number1 dq 123
Second mistake:
printInt number1
The macro gets the argument as string. So, mov rax, %1
will be solved to mov rax, number1
. In NASM, RAX
will get the address of number1
, not the value. Change it to
printInt [number1]
Third mistake:
div rax
means: Divide RDX:RAX by RAX, store the result in RAX and the remainder in RDX. This will always result in RAX=1 and RDX=0. Use another register with the value 10.
Fourth mistake:
pop rsi
The SYSCALL/RAX=1 routine of the kernel expects a pointer in RSI, not a number. There are several ways to address the problem. I leave that to your imagination.
Upvotes: 2