在ASM中显示64位寄存器

时间:2014-10-12 21:20:35

标签: linux fasm

这是我在Linux下进行64位汇编的第一次尝试。我正在使用FASM。

我正在将64位寄存器十六进制值转换为字符串。它工作正常,直到达到最后的数字。我无法弄清楚我的代码究竟出了什么问题。也许有一些关于64编程的东西,我不知道或者使用系统调用(我也是linux noob)

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

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我相信打印最后一位数的问题来自你如何加载r9。如果在输入时,rsp为100.你减去8(rsp = 92),然后用rsp-8加载r9(r9 = 84)。大概你的意思是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