【注意】内联汇编(语句)分为基本和扩展asm语句
匿名2023/07/31 19:52:25提问
    视频纠错文档纠错lab1student
410

感谢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”);
  
怎么讲的与实际的情况相矛盾?
   
带着这个问题,我阅看了本节(4.3)ppt中“CC内联汇编-参考资料”指定的内容:“GCC Manual 6.41 –6.43(version 4.9.2)”和“Inline assembly for x86 in Linux”。
   
但这两处只讲扩展asm(extended asm)语句结构,甚至都没有提到“基本asm(basic asm)语句”这个概念。
   
后来在GNU网站找到了一个网页https://gcc.gnu.org/onlinedocs/gcc.pdf(GCC Manual, 版本为5.0.0 pre-release),内面6.43节(How to Use Inline Assembly Language in C Code)介绍:
   
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 ] ])
(还有一种形式,不再赘述)
    
(还可参考GCC-Inline-Assembly-HOWTO
      
至此,答案找到了:对于基本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)需要完善。

回答(2
    推荐问答
      Simple Empty
      暂无数据