gpt4 book ai didi

c++ - 试图理解来自 g++ 的简单反汇编代码

转载 作者:太空狗 更新时间:2023-10-29 21:35:37 24 4
gpt4 key购买 nike

我仍在努力使用 g++ 内联汇编程序并试图了解如何使用它。

我从这里改编了一段代码:http://asm.sourceforge.net/articles/linasm.html (引自 gcc 信息文件中的“带 C 表达式操作数的汇编程序指令”部分)

static inline uint32_t sum0() {
uint32_t foo = 1, bar=2;
uint32_t ret;
__asm__ __volatile__ (
"add %%ebx,%%eax"
: "=eax"(ret) // ouput
: "eax"(foo), "ebx"(bar) // input
: "eax" // modify
);
return ret;
}

我编译了禁用优化:

g++ -Og -O0 inline1.cpp -o test

反汇编代码让我疑惑:

(gdb) disassemble sum0
Dump of assembler code for function sum0():
0x00000000000009de <+0>: push %rbp ;prologue...
0x00000000000009df <+1>: mov %rsp,%rbp ;prologue...
0x00000000000009e2 <+4>: movl $0x1,-0xc(%rbp) ;initialize foo
0x00000000000009e9 <+11>: movl $0x2,-0x8(%rbp) ;initialize bar
0x00000000000009f0 <+18>: mov -0xc(%rbp),%edx ;
0x00000000000009f3 <+21>: mov -0x8(%rbp),%ecx ;
0x00000000000009f6 <+24>: mov %edx,-0x14(%rbp) ; This is unexpected
0x00000000000009f9 <+27>: movd -0x14(%rbp),%xmm1 ; why moving variables
0x00000000000009fe <+32>: mov %ecx,-0x14(%rbp) ; to extended registers?
0x0000000000000a01 <+35>: movd -0x14(%rbp),%xmm2 ;
0x0000000000000a06 <+40>: add %ebx,%eax ; add (as expected)
0x0000000000000a08 <+42>: movd %xmm0,%edx ; copying the wrong result to ret
0x0000000000000a0c <+46>: mov %edx,-0x4(%rbp) ; " " " " " "
0x0000000000000a0f <+49>: mov -0x4(%rbp),%eax ; " " " " " "
0x0000000000000a12 <+52>: pop %rbp ;
0x0000000000000a13 <+53>: retq
End of assembler dump.

正如预期的那样,sum0() 函数返回了错误的值。

有什么想法吗?到底是怎么回事?如何正确处理?

-- 编辑--根据@MarcGlisse 的评论,我尝试过:

static inline uint32_t sum0() {
uint32_t foo = 1, bar=2;
uint32_t ret;
__asm__ __volatile__ (
"add %%ebx,%%eax"
: "=a"(ret) // ouput
: "a"(foo), "b"(bar) // input
: "eax" // modify
);
return ret;
}

看来我一直遵循的教程具有误导性。输出/输入字段中的“eax”并不表示寄存器本身,而是缩写表中的 e、a、x 缩写。

不管怎么说,我还是没弄对。上面的代码导致编译错误:“asm”操作数具有不可能的约束。

我不明白为什么。

最佳答案

x86 的扩展内联汇编约束在 official documentation 中列出.
complete documentation也值得一读。

可以看到,约束都是单个字母。
foo 的约束“eax”指定了三个约束:

a
   The a register.

x
   Any SSE register.

e
   32-bit signed integer constant, or ...

由于您告诉 GCC eax 已被破坏,因此它无法将输入操作数放在那里,而是选择 xmm0

When the compiler selects the registers to use to represent the input operands, it does not use any of the clobbered registers

proper constraint is simply "a" .
您需要从 clobber 中删除 eax(顺便说一句,由于高位归零,它应该是 rax)(并添加“cc”)。

关于c++ - 试图理解来自 g++ 的简单反汇编代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41891834/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com