Assembly
到计算机的核心内部,发送到机器任何部分的每个信号都是一系列电脉冲。 如果电脉冲高,例如5伏,表示发送二进制1位。 如果电脉冲低,例如0伏,表示发送二进制0位。 把4个二进制数字放在一起,你会得到一个半字节(nibble)。 把8个放在一起,你会得到一个字节(byte)。 把16个放在一起,你会得到一个字(word)。 计算机理解这些部分中的命令,但人类可很难理解。 所以人们开发了一种更好的查看此类信息的方式,那就是使用十六进制。 通常不需要16个位就可以显示一个命令,记住以下命令变得更加方便:(译者注:原文这里好像有些错误,应该主要这里是指的机器码)
90 - No Operation CC - Break E9 - 16 bit jump CD - Interrupt 等。
但是很快,人们了解到这种代码需要用户友好,因此发明了汇编代码。 使用汇编代码,你可以用更易于人类阅读的特殊代码表示计算机操作。 例如JMP 跳转、INT 中断、NOP 空操作等。
汇编程序是读取汇编文件 (通常使用扩展名.asm) 并将其转换为二进制可执行文件的程序。 这非常类似于生成可执行程序的编译器。 但是,汇编程序与编译器的不同之处在于,编译器隐藏了系统的底层细节,而汇编程序则向你暴露了这些细节。
为任何汇编器编写的源代码定义为 “汇编语言。“但这并不意味着什么,因为在完全相同的平台上,每个汇编器可能需要用于完全相同的程序的不同源代码。
汇编语法
在汇编中,每个指令 (或操作/运算符/操作码) 后面都有一个逗号分隔的参数 (或操作数) 列表。 这些操作数可以是立即值 (即数字,如1,2, 十六进制0x16,0101二进制符号 b),或寄存器registers,或内存memory位置。 例如,
mov eax, 123
这里指令是mov,操作数是eax和123。这里eax是寄存器,123是立即值。
汇编有两个主要的语法: 英特尔语法和AT&T语法。
Intel语法
一般来说,一个运算的第一个操作数是目标操作数,另一个操作数 (或多个操作数) 是源操作数。 例如:
mov eax, 123
mov指令从源操作数获取一个值,并将其放置在目标操作数中,因此该值123将被放置到寄存器eax中。 最初的Intel语法是Intel ASM386汇编程序的语法 (后来也授权给最终已经消失了的RadiSys)。 从那时起,许多汇编程序发明了它的许多变体。 此外,它在大多数在线汇编教程中被使用,因为这些教程中的大多数是在 TASM (使用的是Intel语法) 占主导地位的汇编程序时编写的。
AT&T语法
AT&T语法与Intel语法相反。 操作的数据是从左向右传送。 以下是与上述AT&T语法相同的语句。
mov $123, %eax
还有一些其他与操作数的区别:
- 诸如123之类的字面值以 “$” 为前缀 (请参见上面的示例)。
- 内存位置没有前缀: mov 123, %eax 将存储在123的值移动到eax。
- 寄存器以 “%” 为前缀
- 当使用寄存器作为指针时,将其放在括号中: mov (%eax), %ebx将存储在eax中的指针处的值移动到ebx。
- 当使用带有内存位置的语句 (没有寄存器存在) 时,指令后需要后缀。 例如: movl $123, 123. 需要'l' (代表长整形),告诉汇编器值为32位。
- 指针可以通过前缀常量来偏移:4(%eax) 指向4+%eax。
- 指针可以通过将它们写为 :(%eax,%ebx) 来偏移另一个寄存器,指向 x x
- 最后,如果需要,您可以将其全部组合: 4(%eax,%ebx,2) 将为4+%eax+%ebx*2
另见
文章
- Assemblers
- Inline Assembly
- Opcode syntax 有关AT&T语法差异的更多详细信息
- Learning 80x86 Assembly: 免费提供的在线资源列表,以帮助学习80x86汇编语言编程
外部链接
- GNU Binutils - 包括GNU汇编程序 (gas) 在内的免费软件集合
- gas manual - GNU汇编器 (gas) 官方手册
- NASM - Netwide汇编器的官方网站: NASM
- x86_Assembly - 关于基于x86的个人电脑编写汇编的维基教科书
- The Art of Assembly Language Programming, 在线图书,16位DOS版。(后来的版本集中于作者创建的高级汇编方言。)
- PC ASM, 在线书籍,x86上的32位保护模式组件
- x86 Opcode and Instruction Reference, 指令和操作码的数据库,作为免费的可查看、可搜索和可下载的XML文件。 他们还出售实体版本。