Bri*_*ian 40 c assembly gcc inline-assembly cpu-registers
我记得有一种方法可以使用扩展的gcc内联汇编来读取寄存器值并将其存储到C变量中.我不能为我的生活记住如何形成asm陈述.任何帮助深表感谢.
eph*_*ent 31
到目前为止,与其他答案的方向不同,因为我不确定你想要什么.
Run Code Online (Sandbox Code Playgroud)register int *foo asm ("a5");这
a5是应该使用的寄存器的名称......当然,寄存器名称是依赖于cpu的,但这不是问题,因为特定的寄存器通常对显式汇编程序指令很有用(参见Extended Asm).这两件事通常都要求您根据cpu类型对程序进行条件化.
定义这样的寄存器变量不会保留寄存器; 在流量控制确定变量的值不是活动的地方,它仍可用于其他用途.
-ffixed-REG将名为reg的寄存器视为固定寄存器; 生成的代码永远不应该引用它(除了可能作为堆栈指针,帧指针或其他一些固定的角色).
这可以用更简单的方式复制理查德的答案,
int main() {
register int i asm("ebx");
return i + 1;
}
Run Code Online (Sandbox Code Playgroud)
虽然这是毫无意义的,因为你不知道ebx寄存器里有什么.
如果你把这两个结合起来,用这个来编译gcc -ffixed-ebx,
#include <stdio.h>
register int counter asm("ebx");
void check(int n) {
if (!(n % 2 && n % 3 && n % 5)) counter++;
}
int main() {
int i;
counter = 0;
for (i = 1; i <= 100; i++) check(i);
printf("%d Hamming numbers between 1 and 100\n", counter);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您可以确保C变量始终使用驻留在寄存器中以便快速访问,也不会被其他生成的代码破坏.(很方便,ebx在通常的x86调用约定下是被调用者保存的,所以即使它被调用没有编译的其他函数搞砸了,-ffixed-*它也应该被恢复.)
另一方面,这绝对不是可移植的,并且通常也不是性能优势,因为你限制了编译器的自由.
Ric*_*ton 20
以下是获取ebx的方法:
int main()
{
int i;
asm("\t movl %%ebx,%0" : "=r"(i));
return i + 1;
}
Run Code Online (Sandbox Code Playgroud)
结果:
main:
subl $4, %esp
#APP
movl %ebx,%eax
#NO_APP
incl %eax
addl $4, %esp
ret
Run Code Online (Sandbox Code Playgroud)
"= r"(i)是输出约束,告诉编译器第一个输出(%0)是应该放在变量"i"中的寄存器.在此优化级别(-O5),变量i永远不会存储到存储器中,而是保存在eax寄存器中,该寄存器恰好也是返回值寄存器.
我不知道gcc,但在VS中这是如何:
int data = 0;
__asm
{
mov ebx, 30
mov data, ebx
}
cout<<data;
Run Code Online (Sandbox Code Playgroud)
基本上,我将数据移动ebx到您的变量中data.
这会将堆栈指针寄存器移动到 sp 变量中。
intptr_t sp;
asm ("movl %%esp, %0" : "=r" (sp) );
Run Code Online (Sandbox Code Playgroud)
只需将 'esp' 替换为您感兴趣的实际寄存器(但确保不要丢失 %%),并将 'sp' 替换为您的变量。
Kor*_*icz -1
这不是您要找的吗?
句法:
asm ("fsinx %1,%0" : "=f" (result) : "f" (angle));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
69837 次 |
| 最近记录: |