<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=Opcode_syntax</id>
	<title>Opcode syntax - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=Opcode_syntax"/>
	<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Opcode_syntax&amp;action=history"/>
	<updated>2026-04-07T17:41:57Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=Opcode_syntax&amp;diff=391&amp;oldid=prev</id>
		<title>Zhang3：创建页面，内容为“AT&amp;T语法 (如GAS所理解的，GNU汇编器) 是大多数非Intel平台上的标准语法，但在x86平台上仍然很少见。 但是，AT&amp;T语法是GCC 内联汇编 的默认语法，这是objdump在调试内核时将为你提供的语法。  NASM和FASM使用Intel语法，Intel语法是 Bochs 调试器在调试你的内核时提供的。  == 重要细节 ==  AT&amp;T语法和Intel语法之间存在一些实质性差异，打算使用GN…”</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Opcode_syntax&amp;diff=391&amp;oldid=prev"/>
		<updated>2022-02-06T14:00:55Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“AT&amp;amp;T语法 (如GAS所理解的，GNU汇编器) 是大多数非Intel平台上的标准语法，但在x86平台上仍然很少见。 但是，AT&amp;amp;T语法是GCC &lt;a href=&quot;/index.php?title=Inline_Assembly&quot; title=&quot;Inline Assembly&quot;&gt;内联汇编&lt;/a&gt; 的默认语法，这是objdump在调试内核时将为你提供的语法。  NASM和FASM使用Intel语法，Intel语法是 &lt;a href=&quot;/index.php?title=Bochs&quot; title=&quot;Bochs&quot;&gt;Bochs&lt;/a&gt; 调试器在调试你的内核时提供的。  == 重要细节 ==  AT&amp;amp;T语法和Intel语法之间存在一些实质性差异，打算使用GN…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;AT&amp;amp;T语法 (如GAS所理解的，GNU汇编器) 是大多数非Intel平台上的标准语法，但在x86平台上仍然很少见。&lt;br /&gt;
但是，AT&amp;amp;T语法是GCC [[Inline Assembly|内联汇编]] 的默认语法，这是objdump在调试内核时将为你提供的语法。&lt;br /&gt;
&lt;br /&gt;
NASM和FASM使用Intel语法，Intel语法是 [[Bochs]] 调试器在调试你的内核时提供的。&lt;br /&gt;
&lt;br /&gt;
== 重要细节 ==&lt;br /&gt;
&lt;br /&gt;
AT&amp;amp;T语法和Intel语法之间存在一些实质性差异，打算使用GNU工具的程序员应该意识到这一点。&lt;br /&gt;
转到AT&amp;amp;T语法时，需要寻找以下几个关键内容:&lt;br /&gt;
&lt;br /&gt;
* ''' 区分大小写: ''' MOVL与movl并不相同。&lt;br /&gt;
* ''' 数值基数: ''' 用C语言风格表示: 1表示十进制，01表示八进制，0x01表示十六进制。(不支持英特尔postfix-h语法。) &lt;br /&gt;
* ''' 转义字符: ''' 特殊字符被写成C风格的转义 (\n，\&amp;quot;，\#, \\，...)。 &lt;br /&gt;
* ''' 注释: ''' C样式 (/* ... */) 或shell样式 (# ...)。 &lt;br /&gt;
* ''' 指令语法: ''' 指令以句点开始 (“.align 4” 指在32位边界上对齐，“.word 0x1234” 等同于 “DW 1234h”)。 &lt;br /&gt;
* ''' 字符串: ''' 使用特殊指令定义 .ascii (或.asciz用于零端字符串)。示例: msg: .ascii &amp;quot;Hello, World!\n&amp;quot;” &lt;br /&gt;
* ''' 当前位置地址: ''' 用句点 (&amp;quot;.&amp;quot;，相当于Intel语法 &amp;quot;$&amp;quot;) 表示。 &lt;br /&gt;
* ''' 初始化内存: ''' 使用.fill完成 (大致相当于Intel语法 'times db')。 例: .fill 0x1fe - (. - START) , 1, 0 (其中 '1' 是以字节为单位的大小填充掩码，START是标记代码入口点的标签) 等于Intel语法 times 1FEh - ($-$$) db 0。 (.skip和.space指令可以以类似的方式使用。) &lt;br /&gt;
* '''代码计数器''' 可以多次设置，使用.org指令 (如.org 0x1fe START，其中START是标记代码入口点的标签。 位置分配指令 '.=' 可以以相同的方式使用。 &lt;br /&gt;
*'''16/32 bit code''' 可以通过 .code16 或 .code32 (分别相当于Intel语法 [BITS 16] 和 [BITS 32])来生成。 &lt;br /&gt;
* ''' 目标CPU:''' 使用.arch指令设置。 即使您确定默认值为 “i386”，也可以设置它。 &lt;br /&gt;
* ''' 标签声明: ''' 总是以冒号结尾。 &lt;br /&gt;
* '''新标识符''' 假定出现在行的开头，而不是以冒号结尾，是等价语句的一部分，并且必须后跟等号和赋值。示例: FOO = 0xF00 &lt;br /&gt;
* ''' 指令结束: ''' 用换行符或用分号指定; 后者主要在宏中看到，以允许多行代码。 &lt;br /&gt;
* ''' 换行继续: ''' 与C一样，用反斜杠 ('\') 作为一行中的最后一个字符。这也主要用于宏中。 &lt;br /&gt;
* ''' 寄存器: ''' 始终以百分号为前缀: %eax，%cs，%esp等。 &lt;br /&gt;
* ''' 来源(Source)，目的地(Destination): ''' 移动(Move)，加载(Load)，存储(Store)和类似的操作始终具有 “源，目的地” 顺序的操作数，这与Intel语法非常不同。 因此，“movl %eax, %ebx” 将%eax的值移动到, %ebx。 这是似乎最使人困惑的部分，因为它几乎与Intel语法相反:  &amp;lt;pre&amp;gt;Opcode    Register/Memory-being-modified, Data, Data&amp;lt;/pre&amp;gt;&lt;br /&gt;
* ''' 操作数大小后缀: ''' 后缀始终附加到指令 (x86上的ljmp、lcall和lret除外): movb表示 “move字节”，movw表示 “move字”，movl表示 “move长整形” 等。&lt;br /&gt;
* ''' 直接地址操作数: ''' 直接地址操作数没有前缀。因此，&amp;quot;movl foo, %eax&amp;quot; 将内存位置 “foo” 的内容移动到 %eax。 &lt;br /&gt;
* ''' 立即操作数: ''' 立即操作数以美元符号 ($) 为前缀: “pushl $4” 将0x00000004推到堆栈上。这也适用于标签: &amp;quot;movl $foo, %eax&amp;quot; 将标签foo的值 (即变量foo的地址) 移动到 %eax。 &lt;br /&gt;
* ''' 索引/间接操作数: ''' 索引/间接操作数语法: displacement (base, index, scale)，如: movl %eax, %ss:8(%ebp, 2, 3) (相当于Intel语法 mov dword [ss:ebp + 2 * 3 + 8], eax，也就是说，它将 %eax的值移动到段%ss中的偏移 (%ebp + (2 *3) + 8)。 间接地址的五个操作数中的任何一个都可以省略。 &lt;br /&gt;
* ''' 相对寻址: ''' 相对寻址默认情况下在所有跳转和调用指令中使用。要使用绝对寻址，操作数必须以星号 (*) 为前缀。 &lt;br /&gt;
*'''Far jumps / calls / returns:''' 这些使用特殊的操作码 “ljmp” 、 “lcall” 和 “lret”。&lt;br /&gt;
&lt;br /&gt;
AT&amp;amp;T语法的宏格式:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
.macro &amp;lt;name&amp;gt; &amp;lt;args&amp;gt;&lt;br /&gt;
&amp;lt;operations&amp;gt;&lt;br /&gt;
.endm&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
示例:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
.macro write string&lt;br /&gt;
   movw string, %si&lt;br /&gt;
   call printstr&lt;br /&gt;
.endm&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
这将等同于NASM宏:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
%macro write 1&lt;br /&gt;
   mov si, %1&lt;br /&gt;
   call printstr&lt;br /&gt;
%endmacro&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
此外，cpp和 [[M4]] 宏预处理器通常用于宏处理。&lt;br /&gt;
&lt;br /&gt;
== 将小代码片段从Intel语法转换为AT&amp;amp;T ==&lt;br /&gt;
&lt;br /&gt;
你可以使用以下脚本将代码的短片段 (一行) 从Intel语法转换为AT&amp;amp;T语法:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;#!/bin/bash&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
# Usage:&lt;br /&gt;
#&lt;br /&gt;
# ./inteltoatt [16|32|64] &amp;quot;mov eax, eax \n xor ecx, edx&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$1&amp;quot; in&lt;br /&gt;
16|32|64)&lt;br /&gt;
	bits=&amp;quot;$1&amp;quot;&lt;br /&gt;
	shift ;;&lt;br /&gt;
*)&lt;br /&gt;
	bits=&amp;quot;32&amp;quot; ;;&lt;br /&gt;
esac&lt;br /&gt;
code=&amp;quot;$1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nasm=&amp;quot;$(mktemp)&amp;quot;&lt;br /&gt;
obj=&amp;quot;$(mktemp)&amp;quot;&lt;br /&gt;
objdump=&amp;quot;$(mktemp)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$bits&amp;quot; in&lt;br /&gt;
	16) m=&amp;quot;i8086&amp;quot;       ;;&lt;br /&gt;
	32) m=&amp;quot;i386&amp;quot;        ;;&lt;br /&gt;
	64) m=&amp;quot;i386:x86-64&amp;quot; ;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
echo -e &amp;quot;BITS $bits\n$code&amp;quot; &amp;gt; &amp;quot;$nasm&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nasm &amp;quot;$nasm&amp;quot; -o &amp;quot;$obj&amp;quot;&lt;br /&gt;
objdump -D -b binary -m $m -Maddr${bits},data${bits} &amp;quot;$obj&amp;quot; &amp;gt; &amp;quot;$objdump&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lineno=&amp;quot;$(egrep -m 1 -n '&amp;lt;\.data&amp;gt;\:$' &amp;quot;$objdump&amp;quot; | cut -d':' -f1)&amp;quot;&lt;br /&gt;
lineno=$((lineno+1))&lt;br /&gt;
&lt;br /&gt;
tail -n +$lineno &amp;quot;$objdump&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 另见 ==&lt;br /&gt;
=== 外部链接 ===&lt;br /&gt;
*[http://www.delorie.com/djgpp/v2faq/faq17_1.html DJGPP AT&amp;amp;T Assembly Tutorial]&lt;br /&gt;
*[http://asm.sourceforge.net//howto/Assembly-HOWTO.html Linux Assembly HOWTO]&lt;br /&gt;
*[https://savannah.nongnu.org/projects/gas-user/ GAS/AS End User Help Project]&lt;br /&gt;
*[https://savannah.nongnu.org/projects/pgubook/ Programming from the Ground Up]&lt;br /&gt;
&lt;br /&gt;
[[Category:Assembly]]&lt;/div&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
</feed>