- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我仍在努力使用 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/
我是 C++ 的新手,我在使用这段代码时遇到了问题: string output_date(int day, int month, int year){ string date; if
所以我这样做了 tar cvzf test.zip FP 为了创建目录 FP 的 zip 但是,它会列出 zip 中的目录 FP/ FP/php/ FP/php/pdf/ FP/php/docs/ F
我正在尝试在 Swift、Xcode 7.3(所以是 Swift 2.2)中创建一个通用类,但我似乎无法让它通过编译器: protocol Struct1Protocol { } struct Str
我的测试用例是这样的: class FooTest extends PHPUnit_Framework_TestCase { /** @covers MyClass::bar */ f
我正在尝试将brew install wine作为使electron-builder工作的一步。但是我所能得到的只是以下响应: ==> Installing dependencies for wine
我这样做: string[,] string1 = {{"one", "0"},{"Two", "5"},{"Three","1"}}; int b = 0; for(int i = 0; i <=
我正在尝试使用 SetWindowsHookEx 键盘 Hook Notepad.exe。 如您所见,工作线程正在将其 ASCII 代码(即 wParam)发送到指定的服务器。 UINT WINAPI
我正在尝试将 ListView 实现到我的 Fragment 中,但无论我尝试什么,我都会得到一个 NullPointerException。我检查对象是否为 null 并记录是否为 null,看起来
我尝试在一行中对齐两个 div。使用 float left 属性,一切顺利。但是当我在 div 中使用图像时,它开始产生问题。 所以这是我的示例代码:- Some headi
我目前正在使用此代码来获取图像的灰度图像表示并以 (512, 370, 1) 的格式表示它大批。 img_instance = cv2.imread(df.iloc[i][x_col]) / 255.
总结 我正在创建一个简单的应用程序,它允许用户选择一个包含顶级窗口的进程。用户首先键入 native DLL(而非托管 DLL)的路径。然后用户键入将在 Hook 过程中调用的方法的名称。该方法不得返
我是一名优秀的程序员,十分优秀!