chap1.3_汇编语言
1机器语言与汇编语言
1.2 汇编语言简介
人们通过编写汇编指令,然后使用汇编编译器编译成机器语言。汇编语言比只有0和
1组成的机器语言更容易阅读识别
比如
操作:寄存器BX的内容送到AX中
1 | 1000100111011000 // 机器指令 |
2 常见的汇编编译器
汇编语言目前主要有2种风格式
- intel风格:intel风格
- AT&T风格:多数在linux系统上使用。
汇编编译器有以下几种
- gas编译器: 与gcc搭配食用,不用详细说了。
- masm: 微软开发的编译器,可以忽略掉。
- nasm: 目前看比较优雅,我比较喜欢的一个。
安装nasm编译器
ubuntu下使用命令安装
sudo apt-get install nasm
NASM汇编编译器
1. nasm命令用法:
1 | > nasm.exe -f {formart} -o 生成文件 源文件 |
可以使用查看支持生成的文件的{formart}
2. NASM分段
段(Section): 每个汇编程序都是由段来组成的,有以下的段:
- data:用来声明初始化的数据或常量
- bss:用来声明未初始化的变量
- text:用来存放代码
NASM汇编指令
1. 内存单元
| 名称 | 长度 | 说明 |
|---|---|---|
| byte | 8 位 | 字节 |
| word | 16 位 | 词 |
| dword | 32 位 | 双词 |
| 内存单元表示:[] |
任何被[]包含的变量都是地址。[]表示一个内存单元。内存单元的段地址为ds中的存储数据,偏移地址为[]里面表示的数据。
例如:
1 | mov [gs,0x10] 0x3F |
注释: ;
例如
1 | mov ax,0x02 ;ax=0x02 |
数据类型
数据类型,基本的数据类型如下
byte : byte 字节,8位
word : word 字,16位
dword : double word 双字,32位
qword : quadword 四字,64位
2. 伪指令
什么是伪指令
伪指令(Pseudo Instruction)是用于对汇编过程进行控制的指令,该类指令并不是可执行指令,没有机器代码,只用于汇编过程中为汇编程序提供汇编信息。
**1) 地址: [] **
地址的三种表现方式:
- [立即数],例如 [0xf0]
- [存储器],例如 [ds]
- [存储器 + 立即数],例如 [ds,0xf0]
任何不被[]包含的变量都是地址。[]表示一个内存单元。内存单元的段地址为ds中的存储数据,偏移地址为[]里面表示的数据。
**1)当前指令开始地址:$
被称为当前位置计数器
在汇编程序对源程序进行汇编的过程中,使用地址计数器来保证当前正在汇编的指令地址。地址计数器值可用$来表示,汇编语言也允许用户直接用$来引用地址计数器的当前值,因此,ORG $+5可表示从当前地址开始跳过5个字节存储单元,在指令和伪指令中,也可直接用$表示地址计数器的当前值。
故jmp $进入了一个无限循环。
**2)当前段开始地址:$$ **
例如 $-$$ 代表 当前指令开始地址 - 当前段开始地址
3)写字节:DB,DW,DD
DB, DW,DD 输出(1个字节,2个字节,4个字节)
说明:
- DB:写出一个字节(BYTE)。会按照字节输出
- DW :输出一个字(WORD=2BYTE).也就是输出2个字节(16位)。
- DD :输出两个字(DoubleWord=4BYTE).也就是输出4个字节(32位)
**4)填充:RESB, RESW, RESD
RESB, RESW, RESD 填充(1个字节,2个字节,4个字节)
说明:
RESB 510-($-$$) 意思即是510字节位置(0x1fe) 减去这一行现在的字节位置:132。这些都填入0x00
$表示当前行被汇编后的地址,也就是当前行的地址。$$代表一个section节的开始地址。也就是这个section的开始地址。
也可以使用times 510-($-$$) db 0来表示上面的意思。
5)重复指令或数据:times
说明:
重复指令或数据
例如:
times 510-($-$$) db 0
imes前缀引起指令被汇编多次。其中$$表示是该程序的初始代码段的地址,故该指令将会被执行510-($-$$)次。也就是用0来填充剩下的空间,达到510字节。
6)org指令:指定偏移量
格式:ORG 偏移地址
例如:org 07c00h
ORG伪指令用来指出其后的程序段或数据块存放的起始地址的偏移量。汇编程序汇编时把语句中表达式的值作为起始地址,连续存放ORG语句之后的程序和数据,直到出现一个新的ORG指令。若省略ORG语句,则从本段起始地址开始连续存放。偏移地址的范围为(0x0000=0xffff)
在大多数情况下,不需要用ORG语句设置位置指针。由于段定义语句是段的起点,它的偏移地址为0000H,以后每分配一个字节,位置指针自动加1,所以每条指令都有确定的偏移地址。只有程序要求改变这个位置指针时,才需要安排ORG语句。通常ORG语句可以出现在程序中任何位置上。
使用org 07c00h是因为
- 首先DS是默认为0的
- 引导扇区会被加载在07c00h处,也就是磁盘中的代码和内存的代码有一个偏移量为07c00h
当我们设置了org之后,后面的偏移都会默认在0x7c00的基础上。也就是说,如果不加org的话,我们在代码中指定指令时就必须制定 偏移 + 07c00h 来达到相同的效果了。
7) EQU 定义常量
one equ 1 使用one常量代表1
8) 注释 ;