这个程序集如何函数 return 一个值?
How does this assembly function return a value?
我用 C 编写了一个非常简单的函数,它使用 strlen()
从 <string.h>
到 return char*
变量的长度:
int length(char *str) {
return strlen(str);
}
这是来自 objdump -M intel -d a.out
的相应 x86_64 程序集:
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
这是我目前对代码的理解(如有不妥请指正):
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
如果上面有什么不正确的地方请指正,其次call 1070 <strlen@plt>
return如何取值?因为 strlen() 函数 return 是一个字符串的长度,我本以为有些东西会被移到 rax
寄存器中(我相信它通常用于 return 值).但是没有任何内容被移入 rax
并且它没有在程序集中显示 returned 的值。
最后是地址 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]
how does call 1070 strlen@plt return a value?
strlen
将其结果放入 rax
寄存器,这也是您的 length()
函数应该将 its return值。
在优化下,您的 length()
可以编译成一条指令:jmp strlen
-- 参数已经在 rdi
中,而 return 值将在rax
.
P.S.
Lastly here is the code at address 1070
那不是 strlen
的实际代码。这是一个“PLT 跳转存根”。要了解那是什么,您可以阅读 this blog post.
此外,从那个小地址,你可以看出这是一个 PIE 可执行文件:这些只是相对于图像基地址的偏移量;运行时地址类似于 0x55...
我用 C 编写了一个非常简单的函数,它使用 strlen()
从 <string.h>
到 return char*
变量的长度:
int length(char *str) {
return strlen(str);
}
这是来自 objdump -M intel -d a.out
的相应 x86_64 程序集:
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
这是我目前对代码的理解(如有不妥请指正):
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
如果上面有什么不正确的地方请指正,其次call 1070 <strlen@plt>
return如何取值?因为 strlen() 函数 return 是一个字符串的长度,我本以为有些东西会被移到 rax
寄存器中(我相信它通常用于 return 值).但是没有任何内容被移入 rax
并且它没有在程序集中显示 returned 的值。
最后是地址 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]
how does call 1070 strlen@plt return a value?
strlen
将其结果放入 rax
寄存器,这也是您的 length()
函数应该将 its return值。
在优化下,您的 length()
可以编译成一条指令:jmp strlen
-- 参数已经在 rdi
中,而 return 值将在rax
.
P.S.
Lastly here is the code at address 1070
那不是 strlen
的实际代码。这是一个“PLT 跳转存根”。要了解那是什么,您可以阅读 this blog post.
此外,从那个小地址,你可以看出这是一个 PIE 可执行文件:这些只是相对于图像基地址的偏移量;运行时地址类似于 0x55...