我想編譯一個簡單的C程序(Win7 32bit,Mingw32 Shell和GCC 5.3.0)。 C代碼是這樣的:奇怪的'asm'操作數有不可能的約束錯誤
#include <stdio.h>
#include <stdlib.h>
#define _set_tssldt_desc(n,addr,type) \
__asm__ ("movw $104,%1\n\t" \
:\
:"a" (addr),\
"m" (*(n)),\
"m" (*(n+2)),\
"m" (*(n+4)),\
"m" (*(n+5)),\
"m" (*(n+6)),\
"m" (*(n+7))\
)
#define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr,"0x89")
char *n;
char *addr;
int main(void) {
char *n = (char *)malloc(100*sizeof(int));
char *addr = (char *)malloc(100*sizeof(int));
set_tss_desc(n, addr);
free(n);
free(addr);
return 0;
}
_set_tssldt_desc(n,addr,type)
是一個宏,其主體是彙編代碼。 set_tss_desc(n,addr)
是另一個非常類似於_set_tssldt_desc(n,addr,type)
的宏。主函數中調用了set_tss_desc(n,addr)
宏。
當我試圖編譯這段代碼,編譯器的顯示我下面的錯誤:
$ gcc test.c
test.c: In function 'main':
test.c:5:1: error: 'asm' operand has impossible constraints
__asm__ ("movw $104,%1\n\t" \
^
test.c:16:30: note: in expansion of macro '_set_tssldt_desc'
#define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr,"0x89")
^
test.c:25:3: note: in expansion of macro 'set_tss_desc'
set_tss_desc(n, addr);
^
奇怪的是,如果我的評論援引點出的主要功能,代碼編譯成功。或者,如果我刪除彙編代碼的輸出部分中的一些變量,它也編譯。
#include <stdio.h>
#include <stdlib.h>
#define _set_tssldt_desc(n,addr,type) \
__asm__ ("movw $104,%1\n\t" \
:\
:"a" (addr),\
"m" (*(n)),\
"m" (*(n+2)),\
"m" (*(n+4)),\
"m" (*(n+5)),\
"m" (*(n+6))\
)
//I DELETE "m" (*(n+7)) , code compiled
#define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr,"0x89")
char *n;
char *addr;
int main(void) {
char *n = (char *)malloc(100*sizeof(int));
char *addr = (char *)malloc(100*sizeof(int));
set_tss_desc(n, addr);
free(n);
free(addr);
return 0;
}
有人可以向我解釋爲什麼是這樣以及如何解決這個問題?
我猜不出寄存器。您正在使用* mingw *進行編譯,託管時使用某種調用約定。 –
升級您的編譯器可能會有幫助。 GCC 5相當古老。 GCC 7.2是最新的。我推薦[Nuwen Mingw發行版](https://nuwen.net/mingw.html)作爲Windows的另一個小型開發發行版。 – tambre
使用用戶定義的內聯彙編程序的任何代碼都不是「簡單的C程序」。 –