[英]GCC inline assembly intel syntax “Error: invalid use of register”
我決定嘗試在 c 中為我的基本操作系統使用內聯匯編(使用 intel 語法,因為我習慣於使用 NASM)。 我遇到了一些我無法解決的問題,我試着到處尋找,但沒有任何效果。 在嘗試錯誤消息后顯示的代碼時,GCC 顯示以下消息:
main.c: Assembler messages:
main.c:8: Error: invalid use of register
代碼是:
int main(){
asm("mov ah, 0x00\n\t");
asm("mov al, 0x13\n\t");
asm("int 0x10\n\t");
asm("mov bx, 0xA000\n\t");
asm("mov es, bx\n\t");
asm("mov di, 0\n\t");
asm("mov byte [es:di], 0x0f\n\t"); // Problem line of error.
while(1){
asm("nop");
}
return 0;
}
有人能幫我嗎?
關於這一點有很多要提到的。 首先,您使用的是 Intel 語法,這很好(至少對於 GCC,clang 更難)。 您可以在編譯時使用-masm=intel
,或者在 asm 模板中作為.intel_syntax noprefix
的 hack 開關,然后在 asm 字符串的末尾切換回.att_syntax
,這樣編譯器代碼的 rest 仍然有效。 ( 如何設置 gcc 永久使用 intel 語法? )
接下來,你有很多asm()
塊。 最好有一個,因此您可以為整個塊指定輸入/輸出/clobbers/goto。 這可以很容易地完成,因為 C 連接了相鄰的字符串。
您的代碼中有 NASM 風格的[es:di]
。 在 GAS 的 Intel 語法方言中,段名稱位於方括號之外: es:[di]
。 我還注意到,除非您使用 16 位架構,否則[di]
並不合適。 方括號中的東西必須是平台上指針的大小......
...但是您也在使用int 0x10
,這是一個 BIOS 中斷,所以我猜測 16 位實際上是您想要的。
盡管如此,您確實需要養成指定clobbers的習慣。 即指定你的代碼修改了哪些寄存器,是否修改了條件碼寄存器和memory。 編譯器正在決定將哪些變量保存在寄存器等中,並且不知道您的匯編代碼做了什么。 您必須告訴它您正在修改,例如ax
,所以它知道並可以保存/恢復它。
GCC 並不真正了解分段(它是一個便攜式編譯器,假定一個平坦的ds
es
,不專門研究 x86 到 16 的不同基礎,所以不安全) 例如 GCC 可能會選擇使用rep stosd
來初始化結構或數組。 這里很安全,因為您在 asm 之后的代碼很少。
這是我對您的代碼的重寫。
int main()
{
asm volatile(
".intel_syntax noprefix\n\t"
"mov ah, 0x00\n\t"
"mov al, 0x13\n\t"
"int 0x10\n\t"
"mov bx, 0xA000\n\t"
"mov es, bx\n\t"
"mov di, 0x00\n\t"
"mov byte ptr es:[di], 0x0f\n\t"
".att_syntax" // undo .intel_syntax
: /* output operands */
: /* input operands */
: "ax","bx","di","cc", "memory" /* clobbers */
);
while(1){
// asm("nop"); // unneeded: empty infinite loops are already legal in C.
}
return 0;
}
如果您的代碼修改甚至讀取了您也通過 C 指針訪問的 memory,那么您還將在 clobbers 行中包含"memory"
。 請參閱gcc 的內聯匯編文檔,以及如何指示可以使用內聯 ASM 參數指向的 memory *pointed*?
volatile
在這里不是絕對必要的,因為沒有 output 操作數,asm 語句是隱式的volatile
。 但是最好包含volatile
以明確(對人類讀者)存在可見的副作用(BIOS 調用和存儲到視頻內存)。 因此,如果您確實包含了 output 操作數,它就不會被優化掉。
附錄:一般情況下,使用-masm=intel
進行編譯,而不是在清單中使用.intel_syntax
。 這讓編譯器在替換操作數時使用正確的語法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.