chap1.3_汇编语言

1机器语言与汇编语言

1.2 汇编语言简介

人们通过编写汇编指令,然后使用汇编编译器编译成机器语言。汇编语言比只有0和
1组成的机器语言更容易阅读识别

比如

操作:寄存器BX的内容送到AX中

1
2
1000100111011000              // 机器指令
mov ax,bx // 汇编指令

2 常见的汇编编译器

汇编语言目前主要有2种风格式

  1. intel风格:intel风格
  2. AT&T风格:多数在linux系统上使用。

汇编编译器有以下几种

  1. gas编译器: 与gcc搭配食用,不用详细说了。
  2. masm: 微软开发的编译器,可以忽略掉。
  3. nasm: 目前看比较优雅,我比较喜欢的一个。

安装nasm编译器

ubuntu下使用命令安装

sudo apt-get install nasm

NASM汇编编译器

1. nasm命令用法:

1
> nasm.exe -f {formart} -o 生成文件 源文件

可以使用查看支持生成的文件的{formart}

2. NASM分段

段(Section): 每个汇编程序都是由段来组成的,有以下的段:

  1. data:用来声明初始化的数据或常量
  2. bss:用来声明未初始化的变量
  3. text:用来存放代码

NASM汇编指令

1. 内存单元

名称 长度 说明
byte 8 位 字节
word 16 位
dword 32 位 双词
内存单元表示:[]

任何被[]包含的变量都是地址。[]表示一个内存单元。内存单元的段地址为ds中的存储数据,偏移地址为[]里面表示的数据。

例如:

1
mov [gs,0x10]   0x3F

注释: ;

例如

1
mov ax,0x02    ;ax=0x02

数据类型

  1. 数据类型,基本的数据类型如下

    byte : byte 字节,8位
    word : word 字,16位
    dword : double word 双字,32位
    qword : quadword 四字,64位

2. 伪指令

什么是伪指令

伪指令(Pseudo Instruction)是用于对汇编过程进行控制的指令,该类指令并不是可执行指令,没有机器代码,只用于汇编过程中为汇编程序提供汇编信息。

**1) 地址: [] **

地址的三种表现方式:

  1. [立即数],例如 [0xf0]
  2. [存储器],例如 [ds]
  3. [存储器 + 立即数],例如 [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是因为

  1. 首先DS是默认为0的
  2. 引导扇区会被加载在07c00h处,也就是磁盘中的代码和内存的代码有一个偏移量为07c00h
    当我们设置了org之后,后面的偏移都会默认在0x7c00的基础上。也就是说,如果不加org的话,我们在代码中指定指令时就必须制定 偏移 + 07c00h 来达到相同的效果了。

7) EQU 定义常量

one equ 1 使用one常量代表1 ​

8) 注释 ;