这个汇编函数如何返回值?

pro*_*873 0 c assembly x86-64 calling-convention

我用 C 语言编写了一个非常简单的函数,它使用strlen()from<string.h>返回变量的长度char*

int length(char *str) {

    return strlen(str);
}
Run Code Online (Sandbox Code Playgroud)

以下是相应的 x86_64 程序集objdump -M intel -d a.out

00000000000011a8 <length>:
    11a8:   f3 0f 1e fa             endbr64 
    11ac:   55                      push   rbp
    11ad:   48 89 e5                mov    rbp,rsp
    11b0:   48 83 ec 10             sub    rsp,0x10
    11b4:   48 89 7d f8             mov    QWORD PTR [rbp-0x8],rdi
    11b8:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
    11bc:   48 89 c7                mov    rdi,rax
    11bf:   e8 ac fe ff ff          call   1070 <strlen@plt>
    11c4:   c9                      leave  
    11c5:   c3                      ret 
Run Code Online (Sandbox Code Playgroud)

以下是我目前对代码的理解(如果有任何问题请纠正):

00000000000011a8 <length>:
    11a8:   f3 0f 1e fa             endbr64 
    11ac:   55                      push   rbp  // stack setup, old rbp of previous frame pushed
    11ad:   48 89 e5                mov    rbp,rsp // rbp and rsp point to same place
    11b0:   48 83 ec 10             sub    rsp,0x10 // space is made for arguments
    11b4:   48 89 7d f8             mov    QWORD PTR [rbp-0x8],rdi // rdi stores argument and is moved into the space made on the line 11b0
    11b8:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8] // value at memory address rbp-0x8 aka argument is stored in rax
    11bc:   48 89 c7                mov    rdi,rax // move the value into rdi for function call
    11bf:   e8 ac fe ff ff          call   1070 <strlen@plt> // strlen() is called
    11c4:   c9                      leave  // stack clear up
    11c5:   c3                      ret // return address popped and control flow resumes

Run Code Online (Sandbox Code Playgroud)

如果上面有不正确的地方请纠正我,其次如何call 1070 <strlen@plt>返回值?因为 strlen() 函数返回字符串的长度,并且我认为某些内容会被移入寄存器rax(我相信这通常用于返回值)。但没有任何内容被移入rax,并且它不显示程序集中返回的值。

最后是地址 1070 处的代码(来自调用 1070 strlen@plt)

0000000000001070 <strlen@plt>:
    1070:   f3 0f 1e fa             endbr64 
    1074:   f2 ff 25 45 2f 00 00    bnd jmp QWORD PTR [rip+0x2f45]        # 3fc0 <strlen@GLIBC_2.2.5>
    107b:   0f 1f 44 00 00          nop    DWORD PTR [rax+rax*1+0x0]

Run Code Online (Sandbox Code Playgroud)

Emp*_*ian 6

调用 1070 strlen@plt 如何返回值?

strlen其结果放入rax寄存器中,这也是length()函数应该放置返回值的地方。

在优化下,您length()可以编译成一条指令:jmp strlen-- 参数已经在 中rdi,返回值将在 中rax

聚苯乙烯

最后是地址 1070 处的代码

这不是 的实际代码strlen。这是“PLT 跳转存根”。要了解这是什么,您可以阅读这篇博文

另外,从那个小地址,您可以看到这是一个 PIE 可执行文件:这些只是相对于图像基地址的偏移量;运行时地址将类似于0x55...