考虑以下计划:
#include <stdio.h>
int main(void) {
int foo = 10, bar = 15;
__asm__ __volatile__("add %%ebx,%%eax"
:"=a"(foo)
:"a"(foo), "b"(bar)
);
printf("foo+bar=%d\n", foo);
}
我知道add
指令用于加法,sub
指令用于减法&amp;等等。但我不明白这些界限:
__asm__ __volatile__("add %%ebx,%%eax"
:"=a"(foo)
:"a"(foo), "b"(bar)
);
:"=a"(foo) :"a"(foo), "b"(bar) );
的确切含义是什么?它能做什么 ?当我尝试在这里使用mul
指令时,我会得到以下程序的错误:
#include <stdio.h>
int main(void) {
int foo = 10, bar = 15;
__asm__ __volatile__("mul %%ebx,%%eax"
:"=a"(foo)
:"a"(foo), "b"(bar)
);
printf("foo*bar=%d\n", foo);
}
错误:`mul&#39;
的操作数不匹配那么,为什么我收到此错误?我该如何解决这个错误?我在google上搜索过这些内容,但我无法找到问题的解决方案。我正在使用Windows 10 os&amp;处理器是英特尔核心i3。
答案 0 :(得分:4)
具体含义是什么:“= a”(foo):“a”(foo),“b”(bar));
有关如何将参数传递给asm指令here的详细说明。简而言之,这是说bar
进入ebx寄存器,foo
进入eax,执行asm后,eax将包含foo的更新值。
错误:`mul'
的操作数不匹配
是的,这不是mul
的正确语法。也许您应该花一些时间使用x86汇编程序参考手册(例如,this)。
我还要补充一点,使用内联asm通常是bad idea。
编辑:我无法在评论中回答您的问题。
我不太清楚从哪里开始。这些问题似乎表明你对汇编程序的工作方式没有很好的掌握。试着用SO答案教你asm编程并不实用。
但我可以指出你正确的方向。
首先,考虑一下asm代码:
movl $10, %eax
movl $15, %ebx
addl %ebx, %eax
你明白那是做什么的吗?完成后,eax将会是什么? ebx会是什么?现在,将其与此进行比较:
int foo = 10, bar = 15;
__asm__ __volatile__("add %%ebx,%%eax"
:"=a"(foo)
:"a"(foo), "b"(bar)
);
通过使用“a”约束,您要求gcc将foo
的值移动到eax中。通过使用“b”约束,您要求它将bar
移动到ebx中。它执行此操作,然后执行asm的指令(即add
)。退出asm时,foo
的新值将在eax中。得到它?
现在,让我们看一下mul
。根据我链接到的文档,我们知道语法是mul value
。这看起来很奇怪,不是吗?怎么只有mul
的一个参数? 与的价值是多少?
但是如果你继续阅读,你会看到“总是将EAX乘以一个值”。啊。所以“eax”寄存器总是隐含在这里。所以,如果你要写mul %ebx
,那真的是mul ebx, eax
,但因为它总是 是eax,所以没有真正的意义来写出来。
然而,它比这复杂一点。 ebx可以保存32位值。由于我们使用的是int(而不是unsigned int),这意味着ebx可能有一个大到2,147,483,647的数字。但等等,如果你乘以2,147,483,647 * 10会怎样?好吧,因为2,147,483,647已经是一个很大的数字,你可以存储在寄存器中,结果太大了,不适合eax。因此乘法(总是)使用2个寄存器来输出mul
的结果。这就是当它引用“将结果存储在EDX:EAX中时”所指的链接。
所以,你可以写这样的乘法:
int foo = 10, bar = 15;
int upper;
__asm__ ("mul %%ebx"
:"=a"(foo), "=d"(upper)
:"a"(foo), "b"(bar)
:"cc"
);
和以前一样,这会将ebx和foo放在eax中,然后执行乘法指令。
在asm完成后,eax将包含结果的下半部分,而edx将包含上部。如果foo * bar&lt; 2,147,483,647,然后foo将包含您需要的结果,upper
将为零。否则,事情变得更加复杂。
但就我愿意而言。除此之外,参加asm课程。读一本书。
PS你也可以看看this回答以及随后的3条评论,说明为什么即使你的“添加”例子也是“错误的”。
PPS如果这个答案已经解决了您的问题,请不要忘记点击旁边的复选标记,这样我就可以得到我的业力点。