汇编语言(王爽)
第一章 基础知识
汇编语言的三类指令
(1)汇编指令:机器码的助记符,有对应的机器码
(2)伪指令:没有对应的机器码,由编译器执行,计算机不执行
(3)其它符号,如+,-,*,/等,由编译器识别,没有对应的机器码
指令和数据
在内存或磁盘上,指令和数据没有区别,都是二进制信息
总线
地址总线:一个CPU有N根地址总线,可以说、CPU的地址总线宽度是N,最多可以寻找2的N次方个内存单元
数据总线:宽度决定cpu与外界数据传送速度
控制总线:宽度决定cpu对外部器件的控制能力
第二章 寄存器
CPU的组成
控制器:控制各种器间进行工作
运算器:信息处理
寄存器:进行信息存储
内部总线:连接各种器件,在它们之间进行数据传送
通用寄存器
AX,BX,CX,DX存放一般性的数据,8086cpu寄存器都是16位的,可以存放两个字节(1个字)
AX可以分为AH,AL
8086给出物理地址的方法
(1)在内部用两个16位地址合成的方法形成20位的物理地址
一个称为段地址,一个称为偏移地址
(2)段地址和偏移地址通过内部总线送入地址加法器
(3)地址加法器将两个16位地址合成一个20位的物理地址
物理地址 = 段地址x16+偏移地址
地址加法器将二进制地址左移4位,完成段地址x16
(4)地址加法器通过内部总线将20位物理地址送入 输入输出控制电路
(5)输入输出控制电路将20位物理地址送上地址总线
(6)20位物理地址被地址总线送到存储器
补充:一个x进制的数据左移1位,相当于乘以x
段地址
一个段的起始地址一定是16的倍数,偏移地址16位,代表寻址能力为64KB,故一个段最大长度为64kb
可以用不同的段地址和偏移地址形成同一个物理地址
可以根据需要,将地址连续,起始地址为16的倍数的一组内存单元定义为一个段
CS IP
cs为代码段寄存器,IP为指令指针寄存器
CPU将cs ip指向的内存单元中的内容看作指令,如果说内存中一段信息曾被CPU执行过,
那么,它所在的内存单元必然被cs ip指向过
修改cs ip的指令
mov:传送指令
jump: 用寄存器中的值修改ip
第三章 寄存器(内部访问)
小端模式
高地址内存单元中存放数据高位,低地址存放数据低位
![image-20211108161644405](https://i-blog.csdnimg.cn/blog_migrate/620406ca20bd72693d1cf9f12591a025.png)
用0,1两个内存单元存放数据4E20H
将起始地址为N的字单元称为N地址字单元,如0地址字单元存放4E20H
1地址字单元存放124EH
段地址和[address]
DS用来存放要访问数据的段地址
mov bx, 1000H
mov ds, bx
mov al, [0]
以上三条指令将10000H(1000:0)中的数据读到al中
[]表示一个内存单元,0表示内存单元的偏移地址,mov ds,1000H是非法的
需要有一个寄存器进行中转
mov bx,1000H
mov ds,bx
mov[0], al
将al中的数据送入内存单元10000H中
mov ax,123BH
mov ds, ax
mov al, 0
add al,[0]
add al,[1]
add al,[2]
累加数据段的前三个单元中的数据
栈
段寄存器SS、寄存器SP存放栈顶位置
push ax指令
sp=sp-2,将ax中内容(2266H)送入ss:sp 指向的内存单元处
栈空时,sp指向栈空间最高地址的下一个单元
![image-20211108170139047](https://i-blog.csdnimg.cn/blog_migrate/7ec09fbb8dd6fddc668944bbe1bf249b.png)
pop ax后
![image-20211108170256999](https://i-blog.csdnimg.cn/blog_migrate/2e1d6a5c7e33e2e760c033e401c5685b.png)
pop执行后,2266H任然存在,但是已经不在栈中
push 寄存器 ;将一个寄存器中的数据入栈
pop 寄存器 ;出栈,用一个寄存器接收出栈的数据
在10000H处写入字型数据2266H,不允许 mov 内存单元,寄存器的指令
mov ax, 1000H
mov ss, ax
mov sp, 2
mov ax, 2266H
push ax
第一个汇编程序
;ex1.asm
assume cs:code
code segment
dw 0241h,0242h,0243h,0244h,0245h
start:
mov ax, 0b800h
mov ds, ax
mov bx, 0
mov cx, 5
s: mov ax,cs:[bx]
mov [bx], ax
add bx ,2
loop s
mov ah, 4ch
int 21h
code ends
end start
masm ex1;–>编译源程序
link ex1;–>链接
ex1 -->执行
执行结果
第五章 [bx]和loop指令
[bx]
mov ax, [bx]
将一个内存单元内容送入ax,内存单元长度为2字节,
偏移地址在bx中,段地址在ds中,相当于 (ax)=((ds)*16+(bx))
mov al, [bx]与之类似
mov [bx], ax
将bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将ax中数据送入内存SA:EA处
((ds)*16+(bx))=(ax)
inc
inc bx含义是bx中的内容加1
mov bx, 1
inc bx
执行后bx=2
()
()用于表示一个寄存器或者一个内存单元里的内容
(ax)表示ax中的内容
(20000H)表示内存20000H单元的内容,()中的内存单元地址为物理地址
((ds)*16+(bx))表示:ds中的地址作为段地址add1,bx中的地址为偏移地址add2,
内存add1:add2单元的内容
()中元素可以有三种类型:
- 寄存器名
- 段寄存器名
- 内存单元的物理地址(20位)
idata
用idata表示常量
mov ax, [idata] ;代表mov ax, [1] mov ax, [2]等
mov ax, idata ;代表mov bx, 1 mov bx, 2 等
但是,在汇编源程序中,想在[]里用idata给出内存单元的偏移地址,就要在[]前面显示
给出段地址所在的段寄存器,否则编译器masm将[idata]视为idata
mov al, ds:[0]
mov al, [0] ;等效与mov al, 0
loop指令
loop指令格式是 :loop 标号,CPU执行loop指令时,需要两步操作
- (cx)=(cx)-1
- 判断cx值是否为0,不为0则转至标号处执行,为0则顺序执行
注意:
-
标号代表一个地址,标号所标识的地址要在前面
-
cx中保存循环的次数
example
assume cs:code
code segment
mov ax, 2
mov cx, 11
s: add ax, ax
loop s
mov ax, 4c00h
int 21h
code ends
end
段前缀
用于显式指明内存单元的段地址的 ds: cs: ss: es: 在汇编语言中称为段前缀
mov ax, ds:[bx]
mov ax, cs:[bx]
mov ax, ss:[bx]
mov ax, es:[bx]
mov ax, ss:[0]
mov ax, cs:[0]