跳转到内容

itoa函数练习

在nasm如果要正常显示寄存器的十进位整数到终端,需要将每一位数当成一个byte并加上48(Ascii的0),才是文字形式的内容,这个动作就是c函式库的itoa()或任何高级语言的将整数转成字串的函数

一般这时候要转的目标是一个64位寄存器,数字上限最大是16个F,换成十进制是18446744073709551615,最多20个数字,空间可以准备20或24 bytes

内存因为是小端的,如果从最低位开始往上写会得到反过来的数字,可以考虑从最高位往下,.bss段在linux定义后内容是0,对应的Ascii是null,所以即使印出整句包含空位也会正常显示

  1. 在.bss段准备一个空间

  2. 每次除以10将余数+48存到内存,然后拿商继续除以10,参考div指令

    示例:

    rdi = 1234
    1234 // 10 -> 123 next
    1234 % 10 -> 4
    4 + 48 = 52("2") save
    123 // 10
    ...
  3. 最后商为0将余数处理完结束循环

  4. 印出来 syscall(1) sys_write

  5. 正常结束 syscall(60) sys_exit

查看代码
; nasm -f elf64 itoa.asm -o itoa.o && ld itoa.o -o itoa && ./itoa
global _start
section .bss
output: resq 3
section .text
_start:
; rsi = 18446744073709551615
lea rdi, [output+23]
xor rsi, rsi
not rsi
call itoa
mov eax, 1
mov edi, 1
lea rsi, [output]
mov edx, 24
syscall
mov eax, 60
xor rdi, rdi
syscall
itoa:
mov rcx, 10
mov rax, rsi
itoa_loop:
xor rdx, rdx
div rcx
add edx, 48
mov BYTE [rdi], dl
dec rdi
test rax, rax
jnz itoa_loop
ret