[英]multiplication instruction error in inline assembly
考虑以下程序:
#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
指令用于减法等等。 但是我不明白这些行:
__asm__ __volatile__("add %%ebx,%%eax"
:"=a"(foo)
:"a"(foo), "b"(bar)
);
:"=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”的操作数不匹配
那么,为什么我会收到此错误? 我该如何解决这个错误? 我已经在Google上搜索了这些内容,但找不到我的问题的解决方案。 我正在使用Windows 10 OS,处理器是Intel Core i3。
:“ = a”(foo)的确切含义是:“ a”(foo),“ b”(bar));
还有的参数是如何传递给汇编指令的详细介绍在这里 。 简而言之,就是说bar
进入ebx寄存器, foo
进入eax,在执行asm之后,eax将包含foo的更新值。
错误:“ mul”的操作数不匹配
是的,那不是mul
的正确语法。 也许您应该花一些时间阅读x86汇编程序参考手册(例如this )。
我还要补充一点,使用内联asm通常不是一个好主意 。
编辑:我无法在评论中加入对您问题的回答。
我不太确定从哪里开始。 这些问题似乎表明您根本不了解汇编程序的工作方式。 试图通过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位的数值。 由于我们使用的是整数(而不是无符号整数),因此这意味着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"
);
如前所述,这会将bar放在ebx中,并将foo放在eax中,然后执行乘法指令。
在完成asm之后,eax将包含结果的下部,而edx将包含结果的下部。 如果foo * bar <2,147,483,647,则foo将包含您需要的结果,并且upper
将为零。 否则,事情会变得更加复杂。
但这是我愿意去的。 除此之外,参加ASM课程。 读一本书。
附注:您可能还会看到此答案以及随后的3条注释,这些注释说明了为什么即使您的“添加”示例也是“错误的”。
PPS如果此答案解决了您的问题,请不要忘记单击其旁边的复选标记,以便获得我的业障积分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.