汇编学习--第一天
背景:这本书之前看了大部分,但要批评自己心急了,看了之后实验没做,收获很少,所以决定重新学一遍,记录和分享我在每一章的收获(主要记录实操)。
第一章 基础知识
汇编组成:汇编指令,伪指令,其他符号。
一个存储单元(byte)可以储存8个bit,即8位二进制
最终运行汇编程序的是CPU
第二章 寄存器
8806CPU寄存器:16位,可存放两个字节,14个寄存器:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW。
通用寄存器:AX,BX,CX,DX
通用寄存器可分为两个独立8位寄存器使用:
AX -->AH + AL
BX-->BH + BL
CX-->CH + CL
DX-->DH + DL
AL 为低8位 AH为高8位(low, high)
8086一次可以处理以下两种尺寸的数据:
字节(byte):由8 bit组成,可以存于8位寄存器
字(word):word,一个字由两个字节构成,两字节分别为高位字节和低位字节
;传送指令 mov ax,18 mov ax,bx
;增加指令 add ax,8 add ax,bx
问题2.1
指令 | 指令结束之后AX中的数据 | 指令结束之后BX中的数据 |
mov bx,2000H | 6226H | 2000H |
add ax,bx | 8226H | 2000H |
mov bx,ax | 8226H | 8226H |
add ax,bx | 044CH | 8226H |
计算结果为1044CH,因为AX为16位寄存器,只能存放4位16进制,所以高位1不能在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 |
add al,6 | ax=d888h |
add al,al | ax=d810h |
mov ax,cx | ax=6246h |
高低位计算各管各。
(2)
mov ax,2 add ax,ax add ax,ax add ax,ax
2.7
段地址x16 + 偏移地址 =物理地址
SA X 16 + EA = ADDRESS
CPU可以用不同的段地址和偏移地址形成同一个物理地址
检测点 2.2
(1) 给定段地址为 0001H,仅通过变化偏移地址寻址,CPU 的寻址范围为 0010H 到 1000FH 。
解题过程:
物理地址=SA*16+EA
EA 的变化范围为 0h~ffffh
物理地址范围为(SA*16+0h)~(SA*16+ffffh)
现在 SA=0001h,那么寻址范围为
(0001h*16+0h)~(0001h*16+ffffh)
=0010h~1000fh
(2) 有一数据存放在内存 20000H 单元中,现给定段地址为 SA,若想用偏移地址
寻到此单元。则 SA 应满足的条件是:最小为 1001H ,最大为 2000H 。
当段地址给定为 1001H 以下和 2000H 以上,CPU 无论怎么变化偏移地址都无法
寻到 20000H 单元。
解题过程:
物理地址=SA*16+EA
20000h=SA*16+EA
SA=(20000h-EA)/16=2000h-EA/16
EA 取最大值时,SA=2000h-ffffh/16=1001h,SA 为最小值
EA 取最小值时,SA=2000h-0h/16=2000h,SA 为最大值
2.9 && 2.10
CS:代码段寄存器
IP:指令指针寄存器
任意时刻,CS:IP指向内容作为指令执行
设CS内容为M,IP内容为N,CS:IP = M * 16 + N
问题2.3
1) mov ax,6622h
2) jmp 1000:3
3) mov ax,0000
4) mov bx,ax
5) jmp bx
6) mov ax,0123h
7) 从第三步开始循环执行
要让CPU执行储存在内存单元中指令的首地址
8086CPU工作过程
- 1.从CS:IP指向内存单元读取指令,读取的指令进入指令缓存器
- 2.IP指向下一条指令
- 3.执行指令(转到步骤1)
转移指令jmp更改CS:IP
jmp 5:25C5 ;更改CS:IP
jmp 25 ;更改IP
检测点2.3
四次
1) mov ax,bx
2) sub ax,ax
3) 第三项指令读入之后,IP自动增加
4) jmp ax
Debug命令:
- R:查看,改变CPU寄存器的内容
- D:查看内存中的内容
- E:改写内存中的内容
- U:将内存中的机器指令翻译成汇编指令
- T:执行一条机器指令
- A:以汇编指令格式在内存中写入一条机器指令
R指令查看,改变
D查看内存中的内容
d 1000:0
从地址1000:0开始显示128个内存单元
即1000:0~1000:7F
1000:0000---- 69 ---- i
1000:0011-----3C-----空格
中间"-"分隔前八位和后八位
每个位置的数值(转换成10进制)依次对应后面的ASCII码,没有可显示ASCII码用"."表示
指定范围查看:
d 1000:0 9
一个一个修改内存中的内容
空格表示下一个 enter表示结束
写入字符和字符串
将机器码写入内存
b80100 mov ax,0001
b90200 mov cx,0002
01c8 add ax,cx
第二列就是指令对应的机器码
在上面修改了内存的指令的条件下,我们执行这三条指令
1.修改CS:IP指向第一条指令
2.执行内存中的指令
A命令以汇编指令形式在内存中写入机器指令
实验任务
(1)
运行
(2)
将内存与定位地址到2000:0之后
(3)
FFF00H 也就是 FFF0H * 10 + 0
段地址为FFF0H,偏移地址为0
同样FFFFFH=FFF0H * 10 + FFH
所以直接查看
d fff0:0 ff
用的虚拟环境,所以看不了电脑真正的生产日期
(3)
第三章 寄存器
字单元:存放一个字型数据(16位)的内存单元
起始地址为N的字单元简称为N地址字单元
3.1
问题 3.1
1)20H
2)4E20H
3)12H
4)0012H
5)124EH
3.25
mov指令可完成两种数据传送:
- 1.将数据直接送入寄存器
- 2.将一个寄存器中的内容送入另一个寄存器中
- 3.将一个内存单元中的内容送入一个寄存器中。
寄存器用寄存器名指明
内存单元则需用内存单元的地址来指明
例:
mov bx
mov ds,bx
mov al,[0]
"[...]"表示一个内存单元,"[...]"中的0表示单元的偏移地址。内存单元的段地址自动取ds中的数据为内存单元的段地址。
8086CPU不支持直接将数据储存到段寄存器中
问题3.2
mov bx,1000H
mov ds,bx
mov [0],al
问题 3.3
ax=1123H
bx=8833H
cx=8833H
问题3.4
10000H | 34 |
10001H | 2c |
10002H | 22 |
10003H | 11 |