是否可以使用 AMD 处理器的英特尔语法对 ASM 代码进行编码



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

语法独立于 CPU 体系结构。 例如,在 gcc 或 g++ 中,可以使用任何一种语法。默认值为 AT&T 格式,但".intel_syntax"添加到内联程序集中,可以使用英特尔语法。

示例代码

int main()     {
  __asm__ __volatile__ (
    ".intel_syntax noprefixn"
    "jmp farlabeln"
     "mov  EAX,EAXn"
     "farlabel:n"
     "mov  EAX,EAXn"
     ".att_syntax prefixn"
  );
  return 0;
}

(来源)

杂注noprefix意味着不需要在寄存器名称之前添加%.att_syntax切换回 AT&T 语法,因为生成的程序集代码的其余部分采用这种样式。

根据black的评论,我检查了如果我编译上面的小代码,会调用哪些程序。实际上 gcc 调用生成.s文件(这是汇编代码)的cc1plus,然后调用生成.o(对象)文件的as,然后调用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

在这里,两种风格混合在一起...

根据此链接,汇编语法有两个主要分支。

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

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

因此,至少在理论上,如果汇编程序能够理解提供的语法,则用任一语法编写的两个程序应该编译成完全相同的二进制代码。

使用哪种格式取决于汇编程序支持的内容。 只是为了进一步混淆事情,还有其他变体,例如相当受欢迎的nasm。

最新更新