I have made this simple assembly program that prints an integer in hexadecimal.
It works, but I don't understand why it works with only a stack size of 15, when to print a 64 bit integer including 0x
prefix and a newline, you would need 19 characters.
Also I would like to know if I'm using the stack correctly in print_int
.
[BITS 64]
global start
section .text
hex_char: ; input = dl
cmp dl, 0xa
jb decimal_digit
add dl, 0x27
decimal_digit:
add dl, 0x30
ret
print_int: ; input = rax
print_int_stack_size: equ 0xf
push rbp
mov rbp, rsp
sub rsp, print_int_stack_size
mov rbx, print_int_stack_size
mov byte [rsp + rbx], `\n`
dec rbx
print_int_loop:
mov rdx, 0 ; upper half of dividend
mov rcx, 0x10 ; divisor
div rcx ; rax = quotient, rdx = remainder
call hex_char
mov [rsp + rbx], dl
dec rbx
test rax, rax
jnz print_int_loop
mov byte [rsp + rbx], 'x'
dec rbx
mov byte [rsp + rbx], '0'
dec rbx
mov rax, 0x2000004 ; write syscall
mov rdi, 1 ; fd = stdout
lea rsi, [rsp + rbx + 1] ; text
mov rdx, print_int_stack_size
sub rdx, rbx ; length
syscall
add rsp, print_int_stack_size
pop rbp
ret
test_print_int:
mov rax, 0x0
call print_int
mov rax, 0x1e1face
call print_int
mov rax, 0xfedcba9876543210
call print_int
ret
start:
call test_print_int
mov rax, 0x2000001 ; exit syscall
mov rdi, 0 ; exit status
syscall
I'm using OS X so all the unix syscalls starts at 0x2000000.
I'm compiling and running the code with:
nasm -f macho64 print_int.asm -o print_int.o
ld print_int.o -o print_int -macosx_version_min 10.6
./print_int
... which gives the following output:
0x0
0x1e1face
0xfedcba9876543210