《汇编语言》

书评

虽然本书内容只是汇编的基础知识,但从作者文字中展现出的教学态度,内容编排方式,秒杀无数书籍和教师。这应该是目前为止,我看到的最好的专业教学类书籍。
书中谈到的循序渐进和知识遮蔽的教学原则更让我受益匪浅。
破例给满分好评。

记录

一切数据都是二进制。寄存器CS:IP指向是指令,否则是数据。

一、基础知识

CPU与内存

存储

1存储单元=1Byte=8bit
三类交互总线:

  1. 地址
  2. 控制
  3. 数据

1根总线=1bit

检测点1.1

(1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为8x1024=2^3x2^10=13
寻址为储存单元
(2)1KB的存储器有1024个存储单元。存储单元的编号从0-1023
(3)1KB的存储器可以存储1024x8个bit,1024个Byte。
(4)lGB、1MB、1KB分别是1024Byte。
(5)8080、8088、80286、80386的地址总线宽度分别为16根、20根、24根、32
根,则它们的寻址能力分别为:(64KB)(1M)、(16MB)(4GB)
(6)8080、8088、8086、80286、80386的数据总线宽度分别为8根、8根、16根、16
根、32根。则它们一次可以传送的数据为:(1B)、(1B)、(2B)、(2B、(4B)。
(7)从内存中读取1024字节的数据,8086至少要读512次,80386至少要读256次。
(8)在存储器中,数据和程序以二进制形式存放

内存地址空间

最终运行程序的是CPU,我们用汇编语言编程的时候,必须要从CPU的角度考虑问题。对CPU来
讲,系统中的所有存储器中的存储单元都处于一个统一的逻辑存储器中,它的容量受CPU寻址能力的限
制。这个逻辑存储器即是我们所说的内存地址空间。

二、寄存器

CPU=运算器+控制器+寄存器

通用寄存器

8086的所有寄存器为18位,通用有AX BX CX DX

可分为两个8位寄存器来使用。

H 高位,L 低位。
十六进制可以直观看出数据由两个8位构成。4E20=4E和20两个8位。

汇编指令

mov ax,18 将18送入寄存器AX
mov ah,78 将78送入寄存器AH
add ax,8 将寄存器AX中的数值加上8
mov ax,bc 将寄存器BX中的数据送入寄存器AX
add ax,bx 将AX和BX中的数值相加,结果存在AX中

检测

检测点2,1
(1)写出每条汇编指令执行后相关寄存器中的值。
mov ax, 62627
AX-F4A3H
mov ah, 31H
AX-31A3H
mov al,23H
AX-3123H
add ax,ax
AX-6246H
mov bx, 826CH
BX-826CH
mov cx ax
CX-6246H
mov ax bx
AX-826CH
add ax, bx
AX-04D8H
mov al, bh
AX-0482H
mov ah bl
AX-6C82H
add ah ah
AX-D882H
(2)只能使用目前学过的汇编指令,最多使用4条指令,编程计算2的4次方
MOV AX,2
ADD AX,AX
ADD AX,AX
ADD AX,AX

物理地址

地址加法器:物理地址=段地址x16+偏移地址
物理地址=SA*16+EA

检测点

(1)给定段地址为000IH,仅通过变化偏移地址寻址,CPU的寻址范围为0010H到1000FH」
(2)有一数据存放在内存20000H单元中,现给定段地址为SA,若想用偏移地址寻到此单元。则SA应满足的条件是:最小为1001H,最大为2000H
max=SA*16+FFFFH
min=SA*16+0000H
提示,反过来思考一下,当段地址给定为多少,CPU无论怎么变化偏移地址都无法寻到20000H单元?

段寄存器

段地址:4个段寄存器:CS DS SS ES
CS:代码段寄存器
IP:指令指针寄存器
设CS=M,IP=N,则执行M*16+N单元的指令
CPU工作:
(1)从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器;
(2)IP=IP+所读取指令的长度,从而指向下一条指令
(3)执行指令。转到步骤(1),重复这个过程
CPU将CS:IP指向的内存单元中的内容看作指令,在任何时候,CPU将CS、IP中的内容当作指令的段地址和偏移地址,用它们合成指令的物理地址,到内存中读取指令码,执行。如果说,内存中的。
jimp段地址:偏移地址
jimp某一合法寄存器”指令的功能为:用寄存器中的值修改

检测

下面的3条指令执行后,cpu几次修改IP?都是在什么时候?最后IP中的值是
多少?
mov ax, bx
sub ax, ax
Jmp ax
答:一共修改四次
第一次:读取 mov ax,bx之后
第二次:读取sub ax. ax之后
第三次:读取 Jmp ax之后
第四次:执行 Jmp ax修改IP
最后IP的值为0000,因为最后ax中的值为0000H,所以IP中的值也为0000H

Debug

windows cmd->debug
查看、修改CPU中寄存器的内容:R命令
查看内存中的内容:D命令
修改内存中的内容:E命令(可以写入数据、指令,在内存中,它们实际上没有区别)
将内存中的内容解释为机器指令和对应的汇编指令:U命令
执行CSP指向的内存单元处的指令:T命令
以汇编指令的形式向内存中写入指令:A命令

三、寄存器(内存访问)

2单元=1字单元
DS:段地址寄存器
不能直接将地址写入DS,需要通过中间寄存器
mo bx,1000H
mov ds, bx

push ax 放入栈顶
pop ax 出栈放入ax
段寄存器SS 寄存器SP
SS:SP 指想栈顶元素

四、程序

五、[bx]和loop

mov ax,[bx],将偏移地址bx的单元内容送入ax

cx:存放循环次数

mov cx,循环次数
s:
    //循环执行的程序段
loop s

段前缀

mov ax, ds: [bx]
这些出现在访问内存单元的指令中,用于显式地指明内存单元的段地址的“ds;:”“cs:"“ss:”"“es:”,在汇编语言中称为段前缀。

六、多个段的程序

dw: define word

七、更灵活的地址定位

and or

大小写转换

or 'B',0b0100000
and 'a',0b1011111

八、数据处理的两个基本问题

位置+长度
div 除法
(1)除数:有8位和16位两种,在一个reg或内存单元中。
(2)被除数:默认放在AX或DX和AX中,如果除数为8位,被除数则为16位,默认在AX中存放;如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位。
(3)结果:如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数;如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数
dup 数据重复
db 3 dup(0)=db 0,0,0

九、转移指令

8086CPU的转移行为有以下几类。

  1. 只修改IP时,称为段内转移,比如: Jmp ax。
  2. 同时修改CS和IP时,称为段间转移,比如:jmp1000

jmp

jmp short 标号(转到标号处执行指令)
范围 -128-127

jcxz

指令格式:jcxz标号(如果(cx)=0,转移到标号处执行。)
操作:当(cx)=0时,(IP)=(P)+8位位移

loop

指令格式:loop标号(cx)=(cx)-1,如果(cx)≠0,转移到标号处执行。)
操作:
1) (cx)=(cx)-1;
2) 如果(cx)≠0,(ip)=(ip)+8位位移。

十、call和ret指令

Comments
Write a Comment