感谢Alanpsc指出课程知识点的错误!下面是Alanpsc的信息。
---------------------------------------------------------------------------------------------
发现这个知识点,源于编译含有内联汇编代码的c文件时出现错误。
“在线实验平台”/ucore_lab/related_info/lab1下:
#gcc lab1-ex3.c (Enter)
出现:
lab1-ex3.c: Assembler messages:
lab1-ex3.c:2: Error: bad register name `%%eax'
(实验楼也是一样的情况。)
源文件(lab1-ex3.c)中有:
void inline ex1(void){
asm ("movl $0xffff, %%eax\n");
}
如果把eax前面的两个“%”改成一个“%”,则函数ex1编译正确。
可是,在视频“4.3 GCC内联汇编”讲到Example 1时,说汇编代码与内联汇编的对应关系是(并且强调多加一个“%”):
movl $0xffff, %eax ----> asm (“movl $0xffff, %%eax\n”);
怎么讲的与实际的情况相矛盾?
但这两处只讲扩展asm(extended asm)语句结构,甚至都没有提到“基本asm(basic asm)语句”这个概念。
GCC 提供了两种inline asm statements:basic asm statement和extended asm statement。
其中:
基本asm语句(basic asm statement)语法为
asm [ volatile ] ( Assembler Instructions )
扩展asm语句(extended asm statement)语法为
asm [volatile] ( Assembler Template
: Output Operands
[ : Input Operands
[ : Clobbers ] ])
(还有一种形式,不再赘述)
至此,答案找到了:对于基本asm语句,GCC编译出来的汇编代码就是双引号里的内容。(对于扩展asm语句,内联汇编才比汇编代码多一个%。)
比如,对内联汇编语句“asm (“movl $0xffff, %%eax\n”);”编译,因为它属于基本asm语句的语法格式,得到的汇编代码是“movl $0xffff, %%eax”,此代码不符合AT&T语法(eax前多一个%)。
即,要产生正确的汇编代码“movl $0xffff, %eax”,内联汇编应该是asm (“movl $0xffff, %eax\n”);(eax前只能一个%)。
所以,我认为4.3节“GCC内联汇编”(包括视频和ppt)和实验文件(/ucore_lab/related_info/lab1 lab1-ex3.c)需要完善。