GCC编译后syscall后的两条mov指令作用问询(x86-64/Linux ABI)
关于GCC编译syscall后生成冗余mov指令的疑问
我在排查代码问题时拆解了一个调用syscall的函数,发现经GCC编译后,syscall指令后出现了两条看似完全冗余的mov指令:
mov %rax,-0x10(%rbp) mov -0x10(%rbp),%rax
我理解第一条指令是把syscall的返回值从%rax存入栈帧的-0x10(%rbp)位置,第二条又把这个值读回%rax,看起来完全没有意义。我猜测这可能是某种简易内存屏障,但没找到相关文档,也没法定位到GCC源码里的对应逻辑。另外,生成这段代码的内联汇编使用了memory和cc clobbers,以下是该函数的完整汇编代码供参考:
0000000000401cda <sys_mmap>: 401cda: f3 0f 1e fa endbr64 401cde: 55 push %rbp 401cdf: 48 89 e5 mov %rsp,%rbp 401ce2: 48 89 7d e8 mov %rdi,-0x18(%rbp) 401ce6: 48 89 75 e0 mov %rsi,-0x20(%rbp) 401cea: 89 55 dc mov %edx,-0x24(%rbp) 401ced: 89 4d d8 mov %ecx,-0x28(%rbp) 401cf0: 44 89 45 d4 mov %r8d,-0x2c(%rbp) 401cf4: 4c 89 4d c8 mov %r9,-0x38(%rbp) 401cf8: c7 45 fc 09 00 00 00 movl $0x9,-0x4(%rbp) 401cff: 8b 45 fc mov -0x4(%rbp),%eax 401d02: 48 98 cltq 401d04: 48 8b 55 e8 mov -0x18(%rbp),%rdx 401d08: 48 89 d7 mov %rdx,%rdi 401d0b: 48 8b 55 e0 mov -0x20(%rbp),%rdx 401d0f: 48 89 d6 mov %rdx,%rsi 401d12: 8b 55 dc mov -0x24(%rbp),%edx 401d15: 48 63 d2 movslq %edx,%rdx 401d18: 8b 4d d8 mov -0x28(%rbp),%ecx 401d1b: 48 63 c9 movslq %ecx,%rcx 401d1e: 49 89 ca mov %rcx,%r10 401d21: 8b 4d d4 mov -0x2c(%rbp),%ecx 401d24: 48 63 c9 movslq %ecx,%rcx 401d27: 49 89 c8 mov %rcx,%r8 401d2a: 4c 8b 4d c8 mov -0x38(%rbp),%r9 401d2e: 0f 05 syscall 401d30: 48 89 45 f0 mov %rax,-0x10(%rbp) 401d34: 48 8b 45 f0 mov -0x10(%rbp),%rax 401d38: 5d pop %rbp 401d39: c3 retq
说明:此为x86-64汇编/Linux ABI环境。
内容的提问来源于stack exchange,提问作者Jonathan Wilbur
相关产品推荐
相关产品推荐

