[英]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.