当前位置: 首页 > 知识库问答 >
问题:

在SysV ABI中的edi/esi中传递参数

秋阳荣
2023-03-14

我想在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

共有1个答案

赏星河
2023-03-14

一般来说,rdirsi可以被视为通用寄存器,即您可以将它们用于任意算术和内存操作。它们具有某些特殊含义,因为它们也用作字符串操作的索引寄存器。但是,架构并不关心您是在其中存储字符串指针还是另一个任意64位数字。

关于传递32位值,您只需访问源寄存器的低32位部分:

mov ecx, edi

这只会将最低有效的32位移动到ecx。请注意,如果您传递整个64位,它并没有真正产生影响-如果被调用者只访问32位子寄存器ecx,结果是相同的:

mov rcx, rdi
; ...
; use ecx

关于问题中的示例代码,请注意:您似乎正在64位环境中使用32位样式的系统调用。如果指向buf的指针不适合32位,则可能会中断。64位版本的write系统调用如下所示:

write:
    ; syscall number
    mov rax, 1

    ; all other arguments are already in the right registers
    syscall

    ret

更多信息:

  • 如果在64位代码中使用32位int 0x80LinuxABI会发生什么?
  • x86_64Linux系统调用参数
 类似资料:
  • 我需要在Spark SQL中传递参数。例如,下面的查询是Val timestamp=spark。sql(“从表中选择时间戳”)现在,我有另一个查询要在where类Spark中传递这个时间戳。sql(s“从表B中选择col1,其中timestamp='$timestamp'”。 但是上面的查询返回不匹配的表达式错误。有人能提出解决方案吗

  • 问题内容: 请告知如何将参数传递给使用的函数。 我的例子是不正确的。 问题答案: 您需要创建一个匿名函数,以便不会立即执行实际函数。

  • 但是,当我试图将此代码更改为以下代码时,我得到了一个错误-错误:Main method,在类MyClass中找不到,请将Main method,定义为:public static void Main(string[]args)。我需要接收owner和consumerName作为我的程序的参数/输入。 ,这是怎么做到的?

  • 如果C使用cdecl调用约定,为什么godbolt (gcc 9.3)显示参数在edi中被传递?我在这上面找不到任何东西

  • 嗨,我想从一个页面移动到另一个页面,并传递paramters和。如果URL中没有这些参数,我可以用react router实现这一点吗? 我正在使用查看https://github.com/rackt/react-router/blob/master/docs/guides/overview.md#dynamic-segments和解决方案,但在将params传递给URL之前,它无法工作。 编辑1

  • 我有一个简单的POJO: 和一个简单的假冒客户端: 根据拉动请求#667,我期望这被翻译为: 但我得到的是: 请注意,参数在请求主体中传递,而不是作为传递。 它试图调用的endpoint定义为: 我错过了什么?如何使用将其作为查询参数传递?