前言
为了深入了解JVM虚拟机,需要一定的汇编基础,且汇编作为底层语言,在思想上可以带来一定的启发、以及对汇编语言一直的向往,所以学习汇编语言。
目标
预计用20天时间完成《汇编语言(第二版)》的学习。
笔记
第一章
1.1
机器语言就是机器能直接执行的指令集
机器语言是0,1存在难维护、难发现错误的问题,引出汇编语言
1.2
汇编指令是机器指令的另一种表达形式(与机器指令一一对应)
1.3
汇编语言有三种命令:
- 汇编指令:机器码的助记符,有对应的机器码。
- 伪指令:没有机器码、由编译器识别并执行。计算机不执行
- 其他符号:如+、-、*、/,由编译器识别,没有机器码
1.4
要灵活的利用汇编语言编程,要了解CPU和内存的交互
1.5
指令和数据是应用层的概念,在内存和磁盘上无法区分,都是二进制信息
1.6
一个存储单元一般为1B=8bit
1.7
存储器作为数据存放的中间媒介
还需要知道对哪个芯片做什么操作
总线分为三种:1.地址总线、2.数据总线、3.控制总线
通过地址总线告诉内存我要的是哪个地址,通过控制总线告诉内存我要干什么,通过数据总线传输数据
通过地址总线告诉内存,我要找哪个存储单元。然后告诉存储单元通过数据总线把数据读或者写
1.8
可寻址存储单元数=2^地址总线数
1.9
数据总线的跟数决定了一次能向内存写入的数据位数
1.10
小结
(1) 13 。 8KB=81024B,寻址能力为8KB表示能找到81024个存储单元(一个存储单元为1B)所以为2^13为13
(2)1024个,0-1023
(3)10248,1024
(4)102410241024,10241024,1024
(5)64,1,16,4
(6)1,1,2,2,4
(7)512,256
(8)二进制数
1.11
内存地址空间,指CPU可以寻址的空间。10跟地址总线,为1024个存储单元,构成了CPU的寻址空间
1.12
1.13
1.14
存储器分为RAM和ROM,RAM可读可写,ROM只读一般为BIOS
1.15
CPU看待各个物理器件为逻辑存储器,各个逻辑存储器总的内存单元为CPU的内存地址空间
第二章
2.1 通用寄存器
AX、BX、CX、DX。16位,因为8086上一代为8位,为了兼容每个寄存器分为两个单独的8位寄存器
AX=AL+AH、BX=BL+BH、CX=CL+CH、DX=DL+DH
2.2 字在存储器中的存储
字=2字节=16bit,是出于兼容性考虑而衍生的
16进制是H,2进制是B
2.3 几条汇编指令
寄存器存储数据由低到高存储呢,高位溢出。
以AL为寄存器时,认为AH和AL是两个完全不同的寄存器,毫无关系
(1.1)F4A3H
(1.2)31A3H
(1.3)3123H
(1.4)6246H
(1.5)826CH
(1.6)6246H
(1.7)826CH
(1.8)04D8H
(1.9)0482H
(1.10)6C82H
(1.11)D882H
(1.12)D888H
(1.13)D810H
(1.14)6246H
(2)MOV AL 2
ADD AL AL
ADD AL AL
ADD AL AL
2.4 物理地址
2.5 16位结构的CPU
2.6 寻址方式
8086的地址总线由20位,而8086是16位结构,所以需要一种地址合成方法。
所以物理地址=段地址*16+偏移地址
2.7本质含义
*16表示左移4位,即16位变成了地址总线的20位
2.8 段的概念
- 起始地址一定是16的倍数(起始地址需要最低位为0为以后转变为段地址作准备)
-
偏移量为16位即2^16=64KB,所以两个地址段的距离最大位64KB
对8086来说21F60H数据存储在2000:1F60单元中(以段地址+偏移表示)
(1)00010H-1000FH
(2)1001H、2000H
2.9 段寄存器
CS代码段寄存器,IP指令指针寄存器
执行的指令地址为CS*16+IP即CS:IP
有四个段寄存器,CS、DS、SS、ES
2.10 CS和IP
CPU
执行过程
-
从CS:IP中读取指令到指令缓冲器
2.IP寄存器内容增加指令长度,指向下一个地址
3.执行指令,跳转到1
2.11 修改CS和IP的指令
jmp 2AE3:3
jmp ax 表示把AX的值赋给IP
2.12 代码段
代码段是一段连续的内存地址,用来存放代码的地址成为代码段,16的倍数开头,长度小于2^16 (64KB)
4次
mov将指令读入指令缓冲器后,sub将指令读入指令缓冲器后,jum将指令读入指令缓冲器后,执行jum之后
0000H
实验
-u 查看内存汇编指令
-a 修改内存中汇编指令
-d 查看内存二进制
-e 编辑内存二进制,空格继续编辑下一个内存单元
-t 运行指令
-r 查看内存内用
(-r 寄存器编号)修改寄存器内容
第三章
3.1 内存中字的存储
N地址字单元:从地址N开始的存放字的存储单元,高位(逻辑内存地址大的位)存储高位,低位存储低位。
(1)20
(2)4E20
(3)12
(4)0012
(5)124E
3.2 DS和【address】
DS寄存器,存放要访问数据的段地址
mov 支持
- 将内容写入寄存器
- 将一个寄存器的内容写入另一个寄存器(段地址寄存器不能用汇编指令直接写入内容,只能从另一个寄存器写入)
-
将内存内容写入寄存器 (mov ax [...],...为内存地址偏移量,段地址取自DS寄存器)
mov bx, 1000
mov ds, bx
mov [0], al
3.3 字的传送
mov 内存和寄存器时,只要指定寄存器为16位的(ax是16位的,al是8位的)就可以从内存中取一个字在内存和寄存器之间传递(因为数据总线是16位的)
ax:1000
ds:1000
ax:1123
bx:6622
cx:2211
bx:8833
cx:8833
ax:1000
ds:1000
ax:2C34
[0]:34 [1]2C
bx:2C34
bx:1B12
[2]: 12 [3]:1B
3.4 mov、add、sub
段寄存器、寄存器、内存可以互相写入数据,数值可以直接写入寄存器,不能直接写入段寄存器、和内存
mov、add、sub都遵循以上规则
3.5 数据段
与代码段类似,起始地址是16的整数倍,长度小于64KB的内存段。叫法为起始地址为xxx,长度为yyy的数据段。
访问时以ds为存放起始地址访问。
mov ax,1234
mov ds,ax
mov ax,0
add ax,[0]
add ax,[2]
add ax,[4]
AX=2662
BX=E626
AX=E626
AX=2662
BX=D6E6
AX=1D48
AX=2C14
AX=0000
AL=00E6
BX=0000
BL=0026
AL=000C
1 & 2.
mov ax,6622 CS:IP 2000:0003 AX:6622
jmp 0ff0:0100 CS:IP 2000:0008 CS:IP 000F:0100
mov ax,2000 CS:IP 1000:0003 AX:2000
mov ds,ax CS:IP 1000:0005 DS:2000
mov ax,[0008] CS:IP 1000:0008 AX:C389
mov ax,[0002] CS:IP 1000:000B AX:EA66
没有区别,取决于是CS:IP中取的还是,DS中取的
3.6 栈
对于栈研究的角度,仅限于后进先出
3.7 CPU提供的栈机制
8086CPU对于栈的操作都是以字为单位的
push ax表示将ax中的数据送入栈中,pop ax表示将栈顶的元素取出来放入ax中
入栈时,先入高8位,后入低8位(高地址放高8位,低地址放低8位)
SS:SP 指向CPU的栈顶元素
push 执行过程:
先移动SS:SP,再放入元素,SP=SP-2,从高地址向低地址增长
SS:SP 是空栈,所以栈顶指针指向栈空间+1位1000:(000F+1)0010
pop执行过程:
与push一致都是先移动指针,再取元素,取出元素后原来的值不变
3.8 栈顶越界问题
CPU本身不保证越界检测
3.9 push、pop指令
支持,寄存器,段寄存器,内存
mov ax,1000
mov ss,ax
mov sp,0010
push ax
push bx
push ds
mov ax,1000
mov ss,ax
mov sp,0010
mov ax,001A
mov bx,001B
push ax
push bx
mov ax, 0 sub ax,ax(mov 三个字节码,sub两个字节码)
mov bx,0 sub ax,ax
pop bx
pop ax
mov ax,1000
mov ss,ax
mov sp,0010
mov ax,001A
mov bx,001B
push ax
push bx
pop ax
pop bx
mov ax, 1000
mov ss,ax
mov sp, 0002
3.10 栈段
栈段与代码段、数据段一样均为16的整数倍开头,最大长度为64Kb的逻辑连续内存段,是一个逻辑概念CPU不识别
不存在溢出问题,此时正好为SS:0000
64KB,栈地址为SS:SP,SS固定SP为16位,变化范围为0-(2^16-1)为64KB
mov ax,2000
mov ss,ax
mov sp,0010
mov ax,1000
mov ss,ax
mov sp,0000
实验
执行修改SS后,debug的会紧接着执行下一调指令,中间不会中断
第四章 第一个程序
4.1 一个源程序从写出来到执行的过程
- 编写源程序
- 对源程序进行编译链接
- 执行
4.2 源程序
分为指令、伪指令、标号
伪指令
assume cs:xxx 将CS段寄存器指向xxx代码段
xxx segment 代码段xxx开始
xxx ends 代码段xxx结束
end 程序结束
以上伪指令都由编译器执行
指令
程序返回
mov ax, 4c00H
int 21H
4.3 -4.8
第五章 [BX]和loop
【bx】表示偏移量在bx中
(al)表示al的内容。()表达式中不能有:
5.1 [BX]
BE
00
BE
00
BE
BE
5.2 Loop指令
s:
loop
用cx寄存器控制执行次数
5.3 debug中使用loop
g 内存地址偏移量,直接改变IP为指定地址,之前完前面的所有命令
汇编语言中数据不能以字母开头
p 可以跳过当前循环
5.4 debug和masm对于汇编的处理不同
masm中mov ax,[0]必须显示的指定段寄存器应为mov ax, ds:[0]
5.5 loop和[bx]的联合使用
mov ax,ds:[bx] 偏移量只能存储在bx中