在 SysV ABI 的 edi/esi 中传递参数
Pass arguments in edi/esi in SysV ABI
我想用 SysV ABI x86_64 程序集编写程序,到目前为止我已经相当随机地在寄存器中传递了参数。
但是我刚刚在这个论坛上看到,有一个标准。我们必须通过 RDI、RSI、RDX 和 RCX(按照确切的顺序)。
现在我问自己两个问题。
首先,ESI 和 EDI 不是应该只在对字符串进行操作时使用吗?如果我想传递整数而不是字符串作为参数会怎样?
其次,如果我需要传递 32 位参数而不是 64 位参数怎么办?例如,如果我想为系统调用write
创建一个标识符,我会这样写:
;; void write(int fd, const void *buf, size_t count);
;; Inputs : ESI = offset string, EDX = number of characters to write, EBX = file descriptor
;; Outputs : <none>
;; Clobbers : <none>
write:
mov ecx, esi
mov eax, 4
int 0x80
ret
但是对于标准,我如何将值从 64 位寄存器移动到 32 位寄存器?因为我做不到:
mov ecx, rdi ; impossible
一般来说rdi
和rsi
can be treated as general purpose registers,也就是说你可以用它们来进行任意的算术和内存操作。它们具有某些特殊的含义,因为它们也用作字符串操作的索引寄存器。但是,该体系结构并不关心您在其中存储的是字符串指针还是其他任意 64 位数字。
关于传递 32 位值,您可以简单地访问源寄存器的低 32 位部分:
mov ecx, edi
这只会将 least-significant 32 位移动到 ecx
。请注意,如果您传递整个 64 位,它并没有真正的区别 - 如果被调用者仅访问 32 位子寄存器 ecx
,结果是相同的:
mov rcx, rdi
; ...
; use ecx
关于问题中示例代码的小提示:您似乎在 64 位环境中使用 32 位样式的系统调用。如果指向 buf
的指针不适合 32 位,这可能会中断。 write
系统调用的 64 位版本如下所示:
write:
; syscall number
mov rax, 1
; all other arguments are already in the right registers
syscall
ret
更多信息:
- x86_64 Linux syscall arguments
我想用 SysV ABI x86_64 程序集编写程序,到目前为止我已经相当随机地在寄存器中传递了参数。
但是我刚刚在这个论坛上看到,有一个标准。我们必须通过 RDI、RSI、RDX 和 RCX(按照确切的顺序)。
现在我问自己两个问题。
首先,ESI 和 EDI 不是应该只在对字符串进行操作时使用吗?如果我想传递整数而不是字符串作为参数会怎样?
其次,如果我需要传递 32 位参数而不是 64 位参数怎么办?例如,如果我想为系统调用write
创建一个标识符,我会这样写:
;; void write(int fd, const void *buf, size_t count);
;; Inputs : ESI = offset string, EDX = number of characters to write, EBX = file descriptor
;; Outputs : <none>
;; Clobbers : <none>
write:
mov ecx, esi
mov eax, 4
int 0x80
ret
但是对于标准,我如何将值从 64 位寄存器移动到 32 位寄存器?因为我做不到:
mov ecx, rdi ; impossible
一般来说rdi
和rsi
can be treated as general purpose registers,也就是说你可以用它们来进行任意的算术和内存操作。它们具有某些特殊的含义,因为它们也用作字符串操作的索引寄存器。但是,该体系结构并不关心您在其中存储的是字符串指针还是其他任意 64 位数字。
关于传递 32 位值,您可以简单地访问源寄存器的低 32 位部分:
mov ecx, edi
这只会将 least-significant 32 位移动到 ecx
。请注意,如果您传递整个 64 位,它并没有真正的区别 - 如果被调用者仅访问 32 位子寄存器 ecx
,结果是相同的:
mov rcx, rdi
; ...
; use ecx
关于问题中示例代码的小提示:您似乎在 64 位环境中使用 32 位样式的系统调用。如果指向 buf
的指针不适合 32 位,这可能会中断。 write
系统调用的 64 位版本如下所示:
write:
; syscall number
mov rax, 1
; all other arguments are already in the right registers
syscall
ret
更多信息:
- x86_64 Linux syscall arguments