是否可以在AMD处理器的英特尔语法中编写ASM代码?

时间:2016-02-17 20:05:47

标签: assembly syntax compiler-construction intel att

使用英特尔语法或AT& T独立于CPU微体系结构?我的意思是,编译器的任务是将代码(如果它是AT& T或Intel语法独立地)转换为二进制代码,那么可以使用任何语法编写代码吗?

2 个答案:

答案 0 :(得分:3)

语法独立于CPU架构。例如。在中,可以使用任一语法。默认值为AT& T格式,但在内联汇编中添加".intel_syntax"可以使用intel语法。

示例代码

int main()     {
  __asm__ __volatile__ (
    ".intel_syntax noprefix\n"
    "jmp farlabel\n"
     "mov  EAX,EAX\n"
     "farlabel:\n"
     "mov  EAX,EAX\n"
     ".att_syntax prefix\n"
  );
  return 0;
}

source

Pragma noprefix表示不需要在注册名称之前添加%.att_syntax切换回AT& T语法,因为生成的汇编代码的其余部分采用此样式。

根据black的评论,如果编译上面的小代码,我会检查调用哪些程序。实际上调用cc1plus生成.s文件(这是汇编代码),然后调用生成as(对象)文件的.o,然后调用collect2(我假设这会在用户代码周围添加动态加载程序和其他机制),然后cals ld将代码链接在一起并创建可执行文件。

如果调用gcc -S x.cc,则它会在汇编代码生成后立即停止,因此可以看到临时文件。这是生成的代码:

        .file   "x.cc"
        .text
        .globl*  main
        .type   main, @function
main:        
.LFB0:        
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
#APP        
# 9 "x.cc" 1
        .intel_syntax noprefix
jmp farlabel    
mov  EAX,EAX   
farlabel:        
mov  EAX,EAX   
.att_syntax prefix

# 0 "" 2 
#NO_APP        
        movl    $0, %eax
        popl    %ebp
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
        .cfi_endproc
.LFE0:        
        .size   main, .-main
        .ident  "GCC: (Debian 4.7.2-5) 4.7.2"
        .section        .note.GNU-stack,"",@progbits

这里混合了两种风格......

答案 1 :(得分:2)

根据这个link,汇编语法有两个主要分支。

  

x86汇编语言有两个主要的语法分支:Intel语法,   最初用于x86平台和AT& T的文档   语法。1英特尔语法在MS-DOS和Windows世界占主导地位,   由于Unix是创建的,因此Unix世界中的AT& T语法占主导地位   在AT& T贝尔实验室。[2]

可以用来为基于x86的CPU编写汇编程序。汇编程序将采用该语法并将其转换为操作系统可以加载的二进制格式,并且CPU可以执行。

所以至少在理论上,用两种语法编写的两个程序应该编译成完全相同的二进制代码,前提是汇编程序可以理解所提供的语法。

您使用哪种格式取决于您的汇编程序支持的内容。而且为了进一步混淆事物,还有其他变种,例如nasm,它很受欢迎。