【发布时间】:2020-03-26 18:19:51
【问题描述】:
我目前正在学习汇编,我在 64 位 ubuntu 上使用 Intel 语法,使用 nasm。
所以我找到了两个引用系统调用编号的网站:
这个用于 32 位寄存器(eax、ebx、...):https://syscalls.kernelgrok.com
这一个用于 64 位寄存器(rax、rbx、...):https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64
问题是当我使用 64 位系统调用号时我的代码不起作用,但是当我将 32 位寄存器中的“e”替换为“r”时它可以工作,例如在 sys_write我使用 rbx 来存储 fd 而不是 rdi as 并且它可以工作。
我现在很迷茫。此代码不起作用:
message db 'Hello, World', 10
section .text
global _start
_start: mov rax,4
mov rdi, 1
mov rsi, message
mov rdx, 13
syscall
mov rax, 1
mov rdi, 0
syscall
【问题讨论】:
-
如果你写 64 位代码,你应该使用 64 位系统调用。请注意,参数进入与 32 位系统调用不同的寄存器。如果您需要调试帮助,请发布您的代码。
-
您是否也将代码从使用
int 0x80更改为syscall? -
我们不能使用 int 0x80 int 64 bit 吗?
-
section .data message db 'Hello, World', 10 section .text global _start _start: mov rax,4 mov rbx, 1 mov rcx, message mov rdx, 13 int 80h mov rax, 1 mov rdi, 0 int 80h此代码有效 -
使用edit 将您声称不起作用的代码放入您的问题中。
int 0x80系统调用只查看寄存器的低 32 位,这就是为什么您不应该在 64 位代码中使用它们的原因。但这意味着您的代码可以与mov ecx, message一起正常工作,以此类推,如果 它可以与mov rcx, message一起工作。见What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?。您是在int 0x80之前将指针放在esi或rsi中吗?当然这样不行,调用约定和电话号码也不同。
标签: linux assembly x86-64 nasm system-calls