Vil*_*ray 2 linux assembly x86-64 system-calls
我正在使用glibc-2.13-1运行64 位 Debian 4.7.2-5 Linux系统。当我在搜索一些函数调用的汇编代码时,我遇到了这个:libc.a
file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <sync>:
0: b9 a2 00 00 00 mov eax,0xa2
5: 0f 05 syscall
7: 48 3d 01 f0 ff ff cmp rax,0xfffffffffffff001
d: 0f 83 00 00 00 00 jae 13 <sync+0x13>
13: c3 ret
Run Code Online (Sandbox Code Playgroud)
我对这是做什么感到有点困惑。如果这是一台 64 位机器(系统调用如何知道要进行什么系统调用),有什么意义mov eax,0xa2以及为什么不使用rax寄存器?简而言之:这 5 行代码做了什么?
0xa2 是系统调用号。内核使用它来决定要执行的实际功能,因为syscall指令本身不包含任何信息。
至于rax,它确实习惯了。为了延续过去开始的传统,eax是rax.的低 32 位的别名。然而,x64 架构有一个不太为人所知的怪癖:每当您修改低 32 位部分时,高 32 位就会归零。所以,实际上mov eax, 0xa2等价于mov rax, 0xa2,只是它的编码更短。NASM,或者as -O2,甚至会为你做优化。
最后三个指令执行错误处理。如果%rax介于 -1 和 -4095 之间,则表示对于任何Linux 系统调用,系统调用都返回了错误。这是它在原始来源中的样子:
cmpq $-4095, %rax /* Check %rax for error. */
jae __syscall_error /* Branch forward if it failed. */
ret /* Return to caller. */
Run Code Online (Sandbox Code Playgroud)
您看到错误的目标,jae因为您正在反汇编可重定位对象,并且可重定位字段已设置为 0,因为它们将在最终链接时修补。
要查看重定位目标,请将-rswitch添加到objdump命令行:
0000000000000000 <sync>:
0: b8 a2 00 00 00 mov $0xa2,%eax
5: 0f 05 syscall
7: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
d: 0f 83 00 00 00 00 jae 13 <sync+0x13>
f: R_X86_64_PC32 __syscall_error-0x4
13: c3 retq
Run Code Online (Sandbox Code Playgroud)
您可以看到 offset 处的字节f将被修补,以便跳转到 __syscall_error.
有关系统调用的更多信息,请阅读https://cs.lmu.edu/~ray/notes/syscalls/。
还有The Definitive Guide to Linux System Calls博客文章。
| 归档时间: |
|
| 查看次数: |
645 次 |
| 最近记录: |