learningOS开源操作系统社区
  • 首页
  • 训练营
  • 明星学员
  • 共建单位
  • 项目实习
  • 问答论坛
登录
    Copyright © 2024 opencamp.ai All rights reserved.
    【注意】内联汇编(语句)分为基本和扩展asm语句
    匿名2023/07/31 19:52:25提问
      视频纠错文档纠错lab1student
    602

    感谢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
        暂无数据