使用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。