assembly - 学习汇编——回显程序名

标签 assembly x86-64

我正在尝试用汇编语言编写一个简单的程序,它将写出程序的名称。使用 gdb 进行调试,我确定对 sys_write 的调用返回 -14 (EFAULT)。我还能够验证我的 strlen 函数是否正常工作。似乎存在某种内存访问问题,但鉴于 strlen 正在访问相同的内存并且工作正常,我不明白可能出了什么问题。出了什么问题?

谢谢!

完整代码:

section .text
    global _start

_start:
    mov rax, [rsp+8]
    push rax
    call strlen
    add rsp, 8

    mov rdx, rax ; bytes to write
    mov rax, 4 ; sys_write
    mov rbx, 1 ; stdout
    mov rcx, [rsp+8] ; addr of string
    int 0x80

    ; exit
    mov rax, 1
    mov rbx, 0
    int 0x80

strlen:
    mov rax, 0
    mov rbx, [rsp+8]
strlen_loop:
    cmp byte [rbx+rax], 0
    je strlen_end
    inc rax
    jmp strlen_loop
strlen_end:
    ret ; len in rax

最佳答案

正如我在评论中所写,x86_64 使用与 32 位 linux 不同的系统调用方法。特别是 int $0x80 不再是执行此操作的方法(尽管如果安装了 32 位库,它可能会半工作......)。参见例如这个 previous discussion .

在 32 位 x86 上你会做什么:

mov eax, SYSCALL_NUMBER
mov ebx, first_param
mov ecx, second_param
mov edx, third_param
int 0x80

您应该在 x86_64 上执行以下操作:

mov rax, SYSCALL_NUMBER_64 ; This is usually different from the 32-bit version!
mov rdi, first_param
mov rsi, second_param
mov rdx, third_param
syscall

要打印程序名称,请将您的程序更改为以下内容,它应该可以工作。对于其他对启动时程序环境的外观感兴趣的人,请参阅 here .

section .text
    global _start

_start:
    mov rax, [rsp+8]
    push rax
    call strlen
    add rsp, 8

    mov rdi, 1 ; fd = stdout
    mov rsi, [rsp+8] ; buf = addr to string
    mov rdx, rax ; count = strlen(string)
    mov rax, 1 ; write
    syscall

    mov rdi, 0 ; status = 0
    mov rax, 60 ; exit
    syscall

strlen:
    mov rax, 0
    mov rbx, [rsp+8]
strlen_loop:
    cmp byte [rbx+rax], 0
    je strlen_end
    inc rax
    jmp strlen_loop
strlen_end:
    ret ; len in rax

编译使用:

nasm -g -f elf64 -o sc.o sc.asm
gcc -nostartfiles -o sc sc.o

关于assembly - 学习汇编——回显程序名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7006926/

相关文章:

c++ - 为什么我的寄存器不包含我从 asm 计算的值

assembly - 如何获取引导扇区中 nasm 汇编指令的大小?

macos - Segmentation Fault 11链接OS X 32位汇编器

assembly - 将两个字符减去 rax

assembly - GAS AT&T 汇编程序中的 execve() argv

rust - Rust 的 128 位整数 `i128` 如何在 64 位系统上工作?

assembly - 如何在 Assembly 中获取实时按键?

c++ - 如何向 MIPS 中的函数添加 4 个以上的参数?

assembly - 如何使用 "x/i $pc"反汇编 GDB 中的 16 位 x86 引导扇区代码?它被视为 32 位

c++ - 为什么 clang++ 比 adc 更喜欢 adcx