这是我第一次尝试在 Linux 下进行 64 位汇编。我正在使用 FASM。
我正在将 64 位寄存器十六进制值转换为字符串。它工作正常,直到达到最后一位。我无法弄清楚我的代码到底出了什么问题。也许有一些我不知道的 64 位编程或系统调用(我也是 linux 菜鸟)
format ELF64 executable 3
entry start
segment readable executable
start:
mov rax,3c5677h ;final '7' is not displayed
push rax
call REG
;call line
xor edi,edi ;exit
mov eax,60
syscall
;----------------------------------
REG:push rbp ;stack frame setup
mov rbp,rsp
sub rsp,8 ;space for local char
mov rax,[rbp+16];arg
lea r9,[rsp-8] ;local char
mov rcx,16 ;divisor
mov rsi,16 ;16 hex digits for register
.begin: ;get the digit
xor rdx,rdx ;by division
div rcx ;of 16
push rdx ;from back to front
dec rsi
test rsi,rsi
jz .disp
jmp .begin
.disp: ;convert and display digit
inc rsi
pop rax ;In reverse order
add rax,30h ;convert digit to string
cmp rax,39h ;if alpha
jbe .normal
add rax,7 ;add 7
.normal:
mov [r9],rax ;copy the value
push rsi ;save RSI for syscall
mov rsi,r9 ;address of char
mov edx,1 ;size
mov edi,1 ;stdout
mov eax,1 ;sys_write
syscall
pop rsi ;restore RSI for index
cmp rsi,16
je .done
jmp .disp
.done:
add rsp,8 ;stack balancing
pop rbp
ret
预先感谢您的帮助。
最佳答案
我相信打印最后一位数字的问题来自于你加载 r9 的方式。如果在输入时,rsp 为 100。您减去 8 (rsp = 92),然后将 rsp - 8 (r9 = 84) 加载到 r9。大概你的意思是 r9 到 100,所以尝试将其更改为:
lea r9, [rsp+8]
为了更有效的解决方案,更像这样的东西怎么样(假设 rbx 中的值):
mov r9, 16 ; How many digits to print
mov rsi, rsp ; memory to write digits to
sub rsp, 8 ; protect our stack
mov edx, 1 ; size is always 1
mov edi, 1 ; stdout is always 1
.disp:
rol rbx, 4 ; Get the next nibble
mov cl, bl ; copy it to scratch
and cl, 15 ; mask out extra bits
add cl, 0x30 ; Convert to char
cmp cl, 0x39 ; if alpha
jbe .normal
add cl, 7 ; Adjust for letters
.normal:
mov [rsi], cl ; copy the value
mov eax, 1 ; sys_write
syscall ; overwrites rcx, rax, r11
dec r9 ; Finished a digit
jnz .disp ; Are we done?
add rsp, 8 ; Done with the memory
关于linux - 在 ASM 中显示 64 位寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26330099/