跳到內容

itoa函數練習

在nasm如果要正常輸出暫存器的十進位整數到終端,需要將每一位數當成一個byte並加上48(Ascii的0),才是文字形式的內容,這個動作就是c函式庫的itoa()或任何高階語言的將整數轉成字串之函數

一般這時候要轉的目標是一個64位暫存器,數字上限最大是16個F,換成十進位是18446744073709551615,最多20個數字,空間可以準備20或24 bytes

RAM因為是小端序的,如果從最低位開始往上寫會得到反過來的數字,可以考慮從最高位往下,.bss段在linux宣告後內容是0,對應的Ascii是null,所以即使印出整段包含空位也會正常顯示

  1. 在.bss段準備一個空間

  2. 每次除以10將餘數+48存到ram,然後拿商繼續除以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