x86-64 asm中的函数参数

时间:2015-10-01 10:35:01

标签: linux assembly command-line x86-64 calling-convention

所以我必须为学校做这个项目,包括在brainfuck中读取文件并将其解释为汇编。如果我将文件路径保存为.data部分中的字符串,代码就可以工作,但是我想拥有它,以便在终端中启动代码时将文件路径作为参数。

我试过弹出3次(因为堆栈应该是程序/第一个arg的args / addres的数量),然后将%rdi设置为第3个弹出项目的地址处的值,但它返回“./解释器“而不是文件路径

这是有效的代码:

.data
filePath: .asciz "brainF.b"
fileRead: .asicz "r"

.text
.global main
main:
    call fileReader #moves filePath to %rdi, fileRead to %rsi, calls fopen and reads the file
    #code that grabs the read string and interprets it

但我想要的是:

.data
fileRead: .asciz "r"

.text
.global main
main:
    #get 1st argument from terminal(file path) and store it in %rdi
    call fileReader #moves fileRead to %rsi, calls fopen and reads the file

以下是我必须编译和链接的方法(这部分内容无法更改,这就是我的老师要我这样做的方式):

gcc -o interpreter interpreter.s
./interpreter brainF.b

1 个答案:

答案 0 :(得分:4)

64位调用约定在寄存器中传递前6个函数参数,因此argc位于rdi中,argv位于rsi中。第一个命令行参数为argv[1],因此要访问您需要加载8(%rsi)

.globl main
main:
    subq $8, %rsp           # align stack
    movq 8(%rsi), %rsi      # fetch argv[1]
    leaq fmt(%rip), %rdi    # format string
    xorl %eax, %eax         # no xmm used
    call printf             # print
    xorl %eax, %eax         # zero return value
    addq $8, %rsp           # restore stack
    ret                     # done

.data
fmt: .string "First argument is %s\n"
$ ./a.out foo bar
First argument is foo

当然,你应该检查argc,看看你是否收到了足够的论据。