Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 学习程序集-echo程序名_Assembly_X86 64 - Fatal编程技术网

Assembly 学习程序集-echo程序名

Assembly 学习程序集-echo程序名,assembly,x86-64,Assembly,X86 64,我试图在汇编中编写一个简单的程序,它将写出程序名。使用gdb进行调试,我确定对sys_write的调用返回-14(EFAULT)。我还能够验证strlen函数是否正常工作。似乎存在某种内存访问问题,但鉴于斯特伦正在访问相同的内存并且工作正常,我不明白会有什么错误。出什么事了 谢谢 完整代码: section .text global _start _start: mov rax, [rsp+8] push rax call strlen add rsp,

我试图在汇编中编写一个简单的程序,它将写出程序名。使用gdb进行调试,我确定对sys_write的调用返回-14(EFAULT)。我还能够验证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

在开始处添加带有8的rsp,导致
sys\u write
调用获得strlen函数之外的另一个字符串。
strlen
不会改变堆栈,并且以后不会使用推送的
rax
?为什么不删除
push-rax
add-rsp,8
语句,看看这对您来说是如何工作的呢?

正如我在评论中所写的,x86_64对系统调用使用的方法与32位linux不同。尤其是
int$0x80
不再是实现这一点的方法(尽管如果您安装了32位库,它可能会半工作……)。例如,请参见

在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
要打印程序名,请将您的程序更改为以下内容,它应该可以工作。对于其他对程序环境在启动时的外观感兴趣的人,请参阅

使用以下方式编译:

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

尝试在调试器中逐行检查此参数,以验证sys_write的参数是否正确?是的,我在第一个int 0x80处停止执行,并验证所有参数是否正确。我在gdb中使用了x/s$rcx,以确保实际上存在一个我认为应该存在的字符串。在x86_64上,
int$0x80
不用于syscall(并且syscall编号已更改),请参阅前面的许多讨论之一,例如
add rsp,8
是对
\uu cdecl
调用
strlen
的堆栈清理,其中使用了“pushed rax”。。。
nasm -g -f elf64 -o sc.o sc.asm
gcc -nostartfiles -o sc sc.o