linux - 在 ASM 中显示 64 位寄存器

标签 linux fasm

这是我第一次尝试在 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/

相关文章:

assembly - FASM 是低级汇编器而 NASM 是高级汇编器吗?

c - 来自平面汇编器的 Visual Studio LNK1107 : invalid or corrupt file - . obj (COFF)

linux - 从外部源将文本 block 粘贴到 vi 编辑器中的最快方法

linux - 重定向包含的输出字符串

assembly - 在 fasm (MS-DOS) 中访问 0xF000FFFE(计算机类型)处的内存

assembly - 颜色 0-15 组装

linux - 汇编语言中的指针

Linux 按数值排序文件夹

linux - 在 linux shell 中确定当前打开的 URL 的最佳方法

linux - 使用 SED 命令将数字转换为其名称(1=one 等)