【问题标题】:Trouble getting command line arguments in x86 assembly在 x86 程序集中获取命令行参数时遇到问题
【发布时间】:2022-01-13 22:56:29
【问题描述】:

我正在尝试编写一个 x86 版本的“cat”程序,作为汇编中系统调用调用的训练。

我在命令行参数方面遇到了很多困难。 我使用主符号作为入口点,所以我想我会在 %rdi 中找到 argc 参数,在 %rsi 中找到 argv 参数。 实际上 argc 正如预期的那样在 %rdi 中,但是在尝试将 argv[1] 传递给打开的系统调用时,我一直在发生段错误。

不知道我做错了什么,这是我的汇编代码:

main:
    cmp $2, %rdi            // If argc != 2 return 1
    jne .err1

    lea 8(%rsi), %rdi       // Move argv[1] -> %rdi
    xor %rsi, %rsi          // 0 to %rsi -> O_RDONLY
    xor %rdx, %rdx
    mov $2, %rax            // Open = syscall 2
    syscall

    cmp 0, %rax             // If open returns <0 -> exit status 2
    jl .err2

    mov %rax, %rdi          // Move fd to %rdi
    call cat
    ret

.err1:
    mov $1, %rax
    ret
.err2:
    mov $2, %rax
    ret

【问题讨论】:

  • 你如何组装和链接你的代码?如果您不与 libc 链接,则不会将参数计数放入 esi 或将指向参数的指针放入 rdi。相反,您必须从程序加载器将参数放入堆栈的位置检索参数。那么入口点的名称就无关紧要了。
  • 我使用 gcc 组装:gcc -o cat cat.S -no-pie
  • 好的,那么您的代码应该可以工作了。请注意,lea 8(%rsi), %rdi 检索指向第二个参数的指针的指针。如果您想获得指向字符串本身的指针(看起来就像您正在尝试做的那样),请使用mov 8(%rsi), %rdi
  • 这能回答你的问题吗? Linux 64 command line parameters in Assembly

标签: linux assembly x86-64 command-line-arguments


【解决方案1】:

您的代码有两个问题。

首先,您使用lea 8(%rsi), %rdi 检索第二个参数。请注意,rsi 指向一个指向命令行参数的指针数组,因此要检索指向第二个参数的指针,您必须使用 mov 8(%rsi), %rdi 之类的方式取消引用 8(%rsi)

其次,您忘记了cmp $0, %rax0 前面的美元符号。这会导致选择地址0 的绝对地址模式,从而有效地取消引用空指针。要解决此问题,请添加缺少的美元符号以选择立即寻址模式。

当我解决这两个问题时,您发布的代码似乎可以正常工作。

【讨论】:

  • 非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-14
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多