我正在尝试编写一个“hello world”程序来测试g ++中的内联汇编程序。 (仍然倾向于AT& T语法)
代码是:
#include <stdlib.h>
#include <stdio.h>
# include <iostream>
using namespace std;
int main() {
int c,d;
__asm__ __volatile__ (
"mov %eax,1; \n\t"
"cpuid; \n\t"
"mov %edx, $d; \n\t"
"mov %ecx, $c; \n\t"
);
cout << c << " " << d << "\n";
return 0;
}
我收到以下错误:
inline1.cpp: Assembler messages:
inline1.cpp:18: Error: unsupported instruction `mov'
inline1.cpp:19: Error: unsupported instruction `mov'
你能帮助我完成它吗?
韩国社交协会
答案 0 :(得分:2)
您的汇编代码无效。请仔细阅读Extended Asm。这是另一个good overview。 这是一个CPUID示例代码from here:
static inline void cpuid(int code, uint32_t* a, uint32_t* d)
{
asm volatile ( "cpuid" : "=a"(*a), "=d"(*d) : "0"(code) : "ebx", "ecx" );
}
请注意格式:
:
后跟输出操作数:: "=a"(*a), "=d"(*d)
; "=a"
为eax
,"=b
为ebx
:
后跟输入操作数:: "0"(code)
; "0"
表示code
应占据与输出操作数0
相同的位置(在这种情况下为eax
):
后跟破坏的寄存器列表:: "ebx", "ecx"
我收到以下错误:
...
...错误:不支持的指令`mov&#39;
对于mov
指令,因为您没有指定后缀,GAS会尝试推断出一个。看起来GAS无法这样做,因此错误。
This GAS语法指南说:
如果未指定后缀,则没有内存操作数 该指令,GAS从大小推断操作数大小 目标寄存器操作数(最后一个操作数)。
答案 1 :(得分:-1)
我保持@AMA答案是公认的,因为它足够完整。但是我已经对它做了一些考虑,并得出结论认为它不是100%正确。
我试图在GCC中实现的代码如下所示(Microsoft Visual Studio版本)。
int c,d;
_asm
{
mov eax, 1;
cpuid;
mov d, edx;
mov c, ecx;
}
当cpuid在eax设置为1的情况下执行时,将在ecx和edx中返回功能信息。
建议的代码返回eax(&#34; = a&#34;)和edx(=&#34; d&#34;)中的值。 这可以在gdb上看到:
(gdb) disassemble cpuid
Dump of assembler code for function cpuid(int, uint32_t*, uint32_t*):
0x0000000000000a2a <+0>: push %rbp
0x0000000000000a2b <+1>: mov %rsp,%rbp
0x0000000000000a2e <+4>: push %rbx
0x0000000000000a2f <+5>: mov %edi,-0xc(%rbp)
0x0000000000000a32 <+8>: mov %rsi,-0x18(%rbp)
0x0000000000000a36 <+12>: mov %rdx,-0x20(%rbp)
0x0000000000000a3a <+16>: mov -0xc(%rbp),%eax
0x0000000000000a3d <+19>: cpuid
0x0000000000000a3f <+21>: mov -0x18(%rbp),%rcx
0x0000000000000a43 <+25>: mov %eax,(%rcx) <== HERE
0x0000000000000a45 <+27>: mov -0x20(%rbp),%rax
0x0000000000000a49 <+31>: mov %edx,(%rax) <== HERE
0x0000000000000a4b <+33>: nop
0x0000000000000a4c <+34>: pop %rbx
0x0000000000000a4d <+35>: pop %rbp
0x0000000000000a4e <+36>: retq
End of assembler dump.
生成更接近我想要的内容的代码(根据评论的反馈进行编辑):
static inline void cpuid2(uint32_t* d, uint32_t* c)
{
int a = 1;
asm volatile ( "cpuid" : "=d"(*d), "=c"(*c), "+a"(a) :: "ebx" );
}
结果是:
(gdb) disassemble cpuid2
Dump of assembler code for function cpuid2(uint32_t*, uint32_t*):
0x00000000000009b0 <+0>: push %rbp
0x00000000000009b1 <+1>: mov %rsp,%rbp
0x00000000000009b4 <+4>: push %rbx
0x00000000000009b5 <+5>: mov %rdi,-0x20(%rbp)
0x00000000000009b9 <+9>: mov %rsi,-0x28(%rbp)
0x00000000000009bd <+13>: movl $0x1,-0xc(%rbp)
0x00000000000009c4 <+20>: mov -0xc(%rbp),%eax
0x00000000000009c7 <+23>: cpuid
0x00000000000009c9 <+25>: mov %edx,%esi
0x00000000000009cb <+27>: mov -0x20(%rbp),%rdx
0x00000000000009cf <+31>: mov %esi,(%rdx)
0x00000000000009d1 <+33>: mov -0x28(%rbp),%rdx
0x00000000000009d5 <+37>: mov %ecx,(%rdx)
0x00000000000009d7 <+39>: mov %eax,-0xc(%rbp)
0x00000000000009da <+42>: nop
0x00000000000009db <+43>: pop %rbx
0x00000000000009dc <+44>: pop %rbp
0x00000000000009dd <+45>: retq
End of assembler dump.
要明确......我知道有更好的方法可以做到这一点。但这里的目的纯粹是教育性的。只是想了解它是如何工作的; - )
- 编辑(删除个人意见)---