发布者:workWork
;预备===========================================
1, + - * /
2, 十进制 位的概念 数轴表示数字的方式
3, 二进制
4, 十进制转换成二进制
5, 十进制快速转换成二进制
6, 十六进制
7, 十进制转换成十六进制
8, 十进制快速转换成十六进制
9, 十六进制和二进制之间快速互相转换
10,反过来思考的方式
;第一章 基础知识=======================================================
1, 机器指令 0101010101001
2, CPU 执行机器指令
3, 计算机很多部件由谁来组织在一起运行? CPU
4, 汇编指令可以通过编译器翻译成机器指令
5, 编译器就是一个翻译软件,我们需要它是因为 希望用汇编指令 来编程, 因为汇编 更贴近人类思维
6, 指令和数据存放在内存中
7, 指令和数据存放在内存中是没有区别的
8, 内存编号是从0开始的
9, CPU中也存放了一部分指令和数据
10, 地址线决定了CPU的寻址能力
11, 数据线决定了CPU 一次能够传送多少字节的数据
12, 控制线决定了 CPU的 对其他部件的控制能力
13, 1024个内存单元的编号是 从 0 ~ 1023 10 个0 10个1
14, 内存编号为什么是从0开始? 电路上的物理限制 只能表示0 或者1 0000000
15, CPU将内存条,显存,ROM内存都看成 内存空间,对内存空间进行了编号
16,内存有ROM形式和RAM形式
17, CPU 通过端口号 去访问 鼠标键盘... 通过内存地址去访问 内存条 显存 ROM ...
18, CPU 内部有保存 地址信息 和 数据信息的地方,寄存器。
;=======================================================================================
;第二章 寄存器=======================================================================================
1,AX = AH + AL ...范围 0 ~ 65535 0 ~ 255 8位数据-8位寄存器 16位数据-16位寄存器
2,在使用mov 时 要保证 数据与寄存器之间 位数一致性
3,要保证 寄存器与寄存器之间 数据与寄存器之间的 位数一致性
4,mov指令 将逗号右边的给逗号左边的。
5,16位寄存器 进行16位运算 保存16位数据 8位寄存器进行8位运算 保存8位数据
6,段地址*16 + 偏移地址 = 物理地址 ,因为8086CPU有20根地址线,16位寄存器无法表示 所以采取这么一个计算方式
7,CPU任意时刻将 段地址寄存器CS 和 偏移地址寄存器 IP 组合出来的地址 从中读取的内容当作指令
8,指令是有长度的 一条指令可以由多个字节构成 IP寄存器 和指令长度的关系
9,指令执行的过程
;1, CPU从CS:IP 所指向的内存单元读取指令, 存放到 指令缓存器中.
;2, IP = IP + 所读指令的长度,从而指向 下一条指令。
;3, 执行指令缓存器中的内容,回到步骤1
;遗留的问题
;内存编号 为什么是 073F:02CE 这样形式
;内存编号 为什么是 从0 开始的
;CPU怎么区分指令和数据? 下一大章才能告诉大家
;新的问题:
;指令的执行过程为什么是这么设计的?为的是实现什么功能! 下一节课才能告诉大家
;========================================================================================================
;第三章 寄存器(内存的访问)
1,一个字型数据 存放在内存中 可以由 2个连续的地址的内存单元组成
高地址 内存单元存放 字型数据的 高位字节
低地址 内存单元存放 字型数据的 低位字节
1,栈顶标记 标记了 箱子中最上面的这本书的 在箱子中位置
2,栈 箱子
3,入栈 将书 放到箱子中最上面的书的位置的上面
4,出栈 将箱子中最上面的位置的 书 拿走
5,结论 由于不断的入栈 或者 出栈 我们需要不断的修改栈顶标记 来确定 箱子中最上面的书的 在箱子中的位置
6,栈空间 是一段连续的内存单元,也就是一段连续的内存地址
7,push ax 修改SP寄存器中的数值 SP = SP - 2
将 AX 中 字型数据 -> SS:SP 所组合出来的 内存地址 中 入栈
8,pop bx SS:SP所组合出来的内存地址 中的 字型数据 -> bx
修改栈顶标记 SP = SP + 2 成为新的栈顶标记 出栈
9,在8086CPU中 在任意时刻 将 段地址寄存器SS 和偏移地址寄存器 SP 所组合出来的 内存地址 当作栈顶标记!
10,起始地址 + 你所设定的栈的大小的 字节数
0000 + 16(10H) = 10H SS:SP所组合出来的 栈顶标记
11, 栈的最大空间为64KB 例 SS = 1000H SP = 0H push 32768个 又到0 再push 覆盖 从而越界
;==========================================================================================================
问题:
;call 指令 将 IP(000B) 保存到哪里去了(内存的哪里 ) ret 可以拿回(存在栈中 注意 sp 的变化)
课程讲到这里可以算是 第一部分讲完了 课程笔记在视频的左下的 参考资料中下载
所谓的天赋 或者所谓的智商 都不需要
耐心和一些细心的思考
回头看一遍
初学者的
设计者的角度去 去思考 去观察
debug 工具 遇到疑惑
跳出 设置的思维框框
内存分为 数据段 代码段 栈段 先入为主的
为了解决实际问题 工程的问题
不要去禁锢自己的想法
debug 中尝试一下 编程 写一个小的程序 去 测试一下自己的想法 只要符合规则就可以了
;===================================================================================================
伪指令
告诉编译器 也就是翻译软件 这里怎么翻译 那里怎么翻译
对CPU的地址寄存器 进行了 设置 从而 让CPU 安扎我们的 安排 去 访问 数据段 和 栈段
至于代码段 CS 和IP 设置
;================================================================================================================
内存段的安全 数据段 代码段 栈段
随意地向某一段内存空间中 写入内容 是 非常危险的
mov 指令 由于我们不小心修改了 系统存放在 内存中的 重要 数据 或者 指令 导致的 程序的崩溃 系统的崩溃
向安全的内存空间去写入内容
0:200 ~ 0:2FFH
256个字节
就是使用 操作系统 分配给你的 内存空间
在操作系统的环境中, 合法地通过操作系统取得的内存空间 都是安全的
因为操作系统不会让一个程序 所使用的内存空间 和 其他程序 以及系统 自己的 空间 产生冲突
管理内存的程序
操作系统就是干管理内存的时期的
所以在操作系统允许的情况下 程序可以 取得任意容量的 内存空间
一种是 系统加载程序时为 程序分配的 内存空间
程序在执行的过程中 向系统 再去申请内存
;============================================================================================================1
承上启下
我们在一段内存中 存放数据 数据段 存放了我们自己定义的数据
我们可以在一段内存中 存放指令 指令段(代码段) 存放了我们自己定义的指令
我们可以将一段内存定义成 栈空间 因为我们处理数据的时候需要临时性的存放 栈段
我们如何让CPU 按照我们的安排 去访问 这些 内存段呢?
对于数据段来说, 段地址 -》 ds 段地址寄存器 [0],[1]...... mov add sub 指令去访问 这些内存单元
那么cpu 就会将我们定义的 数据段中的内容 当作数据来访问
对于代码段来说。 我们可以 通过修改 CS IP 这2个寄存器 去指向 我们定义的 代码段
这样 CPU 就将 执行 我们定义的 代码段中的 指令
这样CPU就执行力 我们定义代码段中 指令
对于栈段来说, 我们可以通过修改 SS:SP 这2个寄存器 去决定 栈顶标记在哪里
这样cpu 在执行 栈的操作时 比如 push pop 就会将 我们定义的 栈段 当作 栈空间使用
进行临时性的数据存放或者取出
不管我们如何安排,CPU 将内存中 某段内容 当作指令 是因为 CS:IP 指向那里
CPU将某段内存 当作 栈空间 是因为 SS:SP 指向那里
我们一定要清楚,。我们是 如何安排 内存的。以及如何让 CPU 按照我们的 安排去 行事
数据从哪里来
指令从哪里来
临时性的数据 存放到哪里去
取决于 我们对 CPU 中的 地址寄存器的 设置 CS IP SS SP DS 寄存器
;==========================================================================================================
实验任务
1,使用debug,将下面的程序段写入内存,逐条执行,根据指令执行后的实际运行情况填空
mov ax,FFFF
mov ds,ax
mov ax,2200H
mov ss,ax
mov sp,100H
mov ax,ds:[0] ;ax = C0EAH + 0012H
add ax,ds:[2] ;ax = C0FCH
mov bx,ds:[4] ;bx = 30F0H + 2F31H
add bx,ds:[6] ;bx = 6021H
push ax ;sp = FE 修改的内存单元的地址是____2200:FE 内容为 _____C0FCH
push bx ;sp = FC 修改的内存单元的地址是____2200:FC 内容为 _____6021H
pop ax ;sp = _____ FE ax = _______ 6021H
pop bx ;sp = _____ 100H bx = _______ C0FCH
push ds:[4] ;sp = FE 修改的内存单元的地址是____2200:FE 内容为 _____30F0H
push ds:[6] ;sp = FC 修改的内存单元的地址是____2200:FC 内容为 _____2F31H
2,仔细观察图3.19 中的实验过程,然后进行分析 为什么2000:0 ~ 2000:F 中的内容会发生改变?
mov ax,2000H
mov ss,ax
mov sp,10H
mov ax,3123H
push ax
mov ax,3366H
push ax
可能要再做一些实验才能发现其中的规律,如果你在这里就正确回答了这个问题,那么恭喜你,因为你有很好的悟性.
大多数学习者对这个问题还是比较迷惑的,不过不要紧,因为随着课程的进行,这个问题的答案将逐渐变得显而易见.
保存在栈中 每执行一条 t 指令 就会 将寄存器保存到栈中 栈是临时性保存数据
call ip 保存到栈 为了让 ret 指令可以从栈中拿回来
钻牛角尖
设计者的角度 去想这个角度
;========================================================================================================
检测点3.2
1) 补全下面的程序,使其可以将 10000H ~ 1000FH 中的8个字型数据,逆序复制到 20000H ~ 2000FH中
10000H 23H 20000H 33H
10001H 01H 20001H 11H
10002H 66H
10003H 22H
....
1000CH 44H 2000CH 66H
1000DH 78H 2000DH 22H
1000EH 33H 2000EH 23H ;ds:[0] -> 2000E 字型数据
1000FH 11H 2000FH 01H
;20010H sp
mov ax,1000H
mov ds,ax ;ds = 1000H
____________ mov ax,2000H
mov ss,ax
____________ mov sp,10H
____________
push ds:[0] ;1000H*10H + 0 = 10000H 字型数据 0123H ds:[0] -> 栈中
push ds:[2] ;sp = sp - 2
push ds:[4] ;2000E + 2 = 20010H [2] = 2266H
push ds:[6]
push ds:[8]
push ds:[A]
push ds:[C]
push ds:[E]
组合成 20010H SS×10H + SP = 20010H
;========================================================================================================
2) 补全下面的程序,使其可以将 10000H ~ 1000FH 中的8个字型数据,逆序复制到 20000H ~ 2000FH中
10000H 23H 20000H 33H
10001H 01H 20001H 11H
10002H 66H
10003H 22H
....
1000CH 44H 2000CH 66H
1000DH 78H 2000DH 22H
1000EH 33H 2000EH 23H
1000FH 11H 2000FH 01H
mov ax,2000H
mov ds,ax ;ds = 2000H
____________ ;设置 ss :sp mov ax,1000H
mov ss,ax
____________ mov sp,0H
____________
pop ds:[E] ;2000H*10H + E = 2000EH 字型数据 栈中字型数据 -> ds:[E]
pop ds:[C] ;将 栈中的 字型数据 -> ds:[E] sp = sp + 2
pop ds:[A]
pop ds:[8]
pop ds:[6]
pop ds:[4]
pop ds:[2]
pop ds:[0]
;========================================================================================
栈是一种非常重要的机制
;=====================================================================================
笔记的记录方式 是不是也是一种栈
栈的作用
临时性保存数据
mov ax,1000H
mov bx,2000H
push ax
push bx ;注意入栈的顺序
mov ax,0
mov bx,0
pop bx ;注意出栈的顺序
pop ax
;用栈进行数据交换 mov
mov ax,1122H
mov bx,3344H
push ax
push bx
pop ax
pop bx
内存也是一样的
mov ax,1000H
mov ds,ax
push ds:[0]
push ds:[2]
pop ds:[0]
pop ds:[2]
实质上就是一种 mov 移动指令 通过 SS:SP
;========================================================================================================
一个栈 最大的空间能设置为多少?
SP寄存器的变化范围 0 ~ FFFFH 32768个字形数据
SS = 2000H SP = 0
就是设置了一个可以存放 32768个字型数据的箱子
SP 又等于了 0 再入栈 覆盖了原来 栈中的内容
64KB
;=========================================================================================================
栈顶的越界 箱子
栈的设置
pop
栈的大小
指令或者数据
一连串的错误
栈的上限 或者 下限的 寄存器 栈的大小
栈的操作
去安排 栈的大小
;=========================================================================================================
栈 箱子
箱子画在哪里是我决定的
箱子的容量大小也是我决定的
词
决定了CPU 从哪里读取指令
转移指令 修改 CS 或者IP
我们就可以 决定 栈顶标记在哪里
栈在哪里(箱子在哪里) 栈的大小(箱子的大小)
SP = 10H
16byte = 8字型数据 push 可以操作8次
起始地址 + 你所设定的栈的大小的 字节数
0000 + 16(10H) = 10H SS:SP所组合出来的 栈顶标记
栈是如何设置 16的倍数
自己的一个约定 防止一些 稀奇古怪的 问题
;========================================================================================================
栈 箱子 push pop
怀疑和实践的精神 书上 P74页 实验任务(2) 有说这个问题
缺少解决问题想法的基础
栈的作用
;========================================================================================================
栈的概念 内存的角度
入栈 push 将16位寄存器 或者 内存中的 字型数据 -> 栈顶标记的上面 修改栈顶标记
出栈 pop 将栈顶标记 所标识 的 字型数据 -> 16位寄存器 或者 内存中 修改栈顶标记
栈顶标记 在 入栈 和出栈时 所扮演的角色 去 理解这个问题
入栈时 决定了 你放的书(数据)的存放的位置(内存地址) -> 栈顶标记的上面(内存地址) 修改栈顶标记(内存地址)
出栈时 决定了 你拿走书(数据)的位置(内存地址) -> 修改栈顶标记(内存地址)
来确定 箱子中最上面的书(数据)的 在箱子中的位置 (内存地址)
栈顶标记 是 内存地址
段地址 和 偏移地址来表示
在8086CPU中 在任意时刻 将 段地址寄存器SS 和偏移地址寄存器 SP 所组合出来的 内存地址 当作栈顶标记!
push ax 修改SP寄存器中的数值 SP = SP - 2
将 AX 中 字型数据 -> SS:SP 所组合出来的 内存地址 中 入栈
pop bx SS:SP所组合出来的内存地址 中的 字型数据 -> bx
修改栈顶标记 SP = SP + 2 成为新的栈顶标记 出栈
看成是数据
数据从哪里来 寄存器中 内存中
数据的长度 字型数据
;=================================================================================================
栈的概念
内存的角度
预判
程序的角度 栈 是一段连续的内存单元,也就是一段连续的内存地址 段地址 和偏移地址
换一种说法
英语书 一定会被放在 这个箱子中 最上面的这本书的 上面
我们可以为 箱子中 最上面的这本书的 位置 做一个标记
标记代表了 箱子中 最上面的这本书 在 箱子中的 位置
术语
栈顶标记
栈
入栈
出栈
肯定是 箱子中 最上面的 这本书
;=========================================================================================
栈的概念的前言
栈 是一段连续的内存单元,也就是一段连续的内存地址
非常专业的名字
特殊的 访问形式上 mov 移动指令 区别最大地方
mov ax,1000H
mov ds,ax
mov ax,ds:[0]
mov ax,ds:[2]
怀疑和实践的精神 前面所学 反驳
;==================================================================================
检测点3.1
1,在debug中,用 d 0:0 1F 查看内存,结果如下
; 0 1 2 3 4 5 6 7 8 9 A B C D E F
;0000:0000 70 80 F0 30 EF 60 30 E2 - 00 80 80 12 66 20 22 60
0000:0010 62 26 E6 D6 CC 2E 3C 3B - AB BA 00 00 26 06 66 88
下面的指令执行前 AX = 0 BX = 0 写出每条汇编指令执行完后相关寄存器中的值
CPU和内存之间的交互
数据从哪里来 内存地址
数据的长度 字节型数据 字型数据
寄存器是互相独立的
ax = 1
ds = 1
1*10H + 0 = 10H
0*10H + 0 = 0
0*10H + 10H = 10H
; 0 1 2 3 4 5 6 7 8 9 A B C D E F
;0000:0000 70 80 F0 30 EF 60 30 E2 - 00 80 80 12 66 20 22 60
0000:0010 62 26 E6 D6 CC 2E 3C 3B - AB BA 00 00 26 06 66 88
mov ax,1
mov ds,ax ;确定了内存地址中的段地址
mov ax,ds:[0] 字型数据 AX = 2662H
mov bx,ds:[1] 字型数据 BX = E626H
mov ax,bx AX = E626H
mov ax,ds:[0] 字型数据 AX = 2662H + D6E6H = FD48H
mov bx,ds:[2] 字型数据 BX = D6E6H
add ax,bx AX = FD48H + 2ECCH = 2C14H
add ax,ds:[4] 字型数据 AX = 2C14H
mov ax,0 AX = 0
mov al,ds:[2] 字节型数据 AX = 00E6H
mov bx,0 BX = 0000H
mov bl,ds:[c] 字节型数据 BX = 0026H
add al,bl AX = 000CH
希望大家有疑问就去debug中验证,我不一定正确,计算机会告诉你是对的还是错的 实践
2,内存中的情况如图所示
CS = 2000H
IP = 0
DS = 1000H
AX = 0 BX = 0
物理地址 物理地址
10000H B8 mov ax,2000H 20000H B8 mov ax,6622H
10001H 00 20001H 22
10002H 20 20002H 66
10003H 8E mov ds,ax 20003H EA jmp 0FF0:0100H
10004H D8 20004H 00
10005H A1 mov ax,[0008] 20005H 01
10006H 08 20006H F0
10007H 00 20007H 0F
10008H A1 mov ax,[0002] 20008H 89 mov bx,ax
10009H 02 20009H C3
1000AH 00 2000AH
1,写出CPU执行指令序列(用汇编指令写出)
CS:IP
2000H*10H + 0 = 20000H
mov ax,6622H
jmp 0FF0:0100H
mov ax,2000H
mov ds,ax
mov ax,[0008]
mov ax,[0002]
FF0H*10H + 100H = 10000H
读到 指令缓存器中
IP = IP + 所读指令的长度 字节数
执行指令缓存器中的内容 ,回到第一步
物理地址 物理地址
10000H B8 mov ax,2000H 20000H B8 mov ax,6622H
10001H 00 20001H 22
10002H 20 20002H 66
10003H 8E mov ds,ax 20003H EA jmp 0FF0:0100H
10004H D8 20004H 00
10005H A1 mov ax,[0008] 20005H 01
10006H 08 20006H F0
10007H 00 20007H 0F
10008H A1 mov ax,[0002] 20008H 89 mov bx,ax
10009H 02 20009H C3
1000AH 00 2000AH
2,写出CPU执行每条指令后,CS,IP和相关寄存器中的数值.
mov ax,6622H CS = 2000H IP = 0 + 3 = 3 AX = 6622H
jmp 0FF0:0100H CS = 2000H IP = 3 + 5 = 8
mov ax,2000H CS = 0FF0H IP = 100H + 3 = 103H AX = 2000H
mov ds,ax CS = 0FF0H IP = 103H + 2 = 105H DS = 2000H 2000:8 C389H
mov ax,[0008] CS = 0FF0H IP = 105H + 3 = 108H AX = C389H
mov ax,[0002] CS = 0FF0H IP = 108H + 3 = 10BH AX = EA66H 2000:2 EA66H
3,再次体会数据和程序(指令)之间有区别吗?如何确定内存中的信息哪些是数据,哪些是指令(程序)?
CS:IP 读取的都是指令
DS:[偏移地址] 读取 当作数据
去修改 寄存器中的内容 数据从哪来 指令从哪里
;============================================================================
小结
字节型数据 字型数据 在内存中的存放
字型数据 在内存中存储时,需要2个地址连续的内存单元存放,
高位字节 存放在 高地址中
低位字节 存放在 低地址中
mov add sub 实验
数据的长度 内存中的排列不同
字节型数据 01
字型数据 01 00
ds 段地址寄存器 数据段地址寄存器
cs 指令有关
和数据有关
指令和数据在内存中是没有任何区别的 ds:[0] ds:[1]
慢慢讲
cs:ip 指令从哪里来
ds 数据从哪里来
修改寄存器中的内容 去 控制 cpu 控制整个计算机 读取一个字节 读取一个字
写的格式
debug这个工具 , 当你想用某中格式的指令 去 debug中尝试
mov 寄存器,数据 mov ax,8
mov 寄存器,寄存器 mov ax,bx
mov 寄存器,内存单元 mov ax,ds:[0]
mov 内存单元,寄存器 mov ds:[0],ax
mov 段寄存器,寄存器 mov ds,ax
add 寄存器,数据 add ax,8
add 寄存器,寄存器 add ax,bx
add 寄存器,内存单元 add ax,[0]
add 内存单元,寄存器 add [0],ax
sub 寄存器,数据 sub ax,9
sub 寄存器,寄存器 sub ax,bx
sub 寄存器,内存单元 sub ax,[0]
sub 内存单元,寄存器 sub [0],ax
;============================================================================
数据段 编程时候一种数据安排
mov ax,123BH
mov ds,ax
mov al,0
add al,ds:[0]
add al,ds:[1]
add al,ds:[2]
mov ax,123BH
mov ds,ax
mov ax,0
add ax,ds:[0]
add ax,ds:[2]
add ax,ds:[4]
;===========================================================================================================
字节型数据 字型数据
问题3.3
写出下面的指令执行后 寄存器 ax,bx,cx中的值
mov ax,1000H
mov ds,ax ;段地址 字型数据 ;偏移地址
物理地址 内容
mov ax,ds:[0] 10000H 23H ;[0] = 1123H AX = 1123H
mov bx,ds:[2] 10001H 11H ;[1] = 2211H CX = 2211H + 6622H = 8833H
mov cx,ds:[1] 10002H 22H ;[2] = 6622H BX = 6622H + 2211H = 8833H
add bx,ds:[1] 10003H 66H
add cx,ds:[2]
问题3.4
写出下面的指令执行后 内存中 的值
mov ax,1000H
mov ds,ax ;段地址
物理地址 内容
mov ax,2C34H 10000H 34H ;AX = 2C34H
mov ds:[0],ax 10001H 2CH
mov bx,ds:[0] 10002H 12H ;BX = 2C34H - 1122H = 1B12H
sub bx,ds:[2] 10003H 1BH
mov ds:[2],bx
;=========================================================================
字节型数据 字型数据
内存地址去访问内存 8086CPU 段地址和偏移地址
ds段地址寄存器 访问数据用的
mov al,ds:[0] mov 移动指令 CPU中的AL寄存器,内存地址 偏移地址
mov al,ds:[1] 得到里面的内容
mov al,ds:[2] CPU从内存中 读取了 多长的数据?一个字节 8位寄存器
mov al,ds:[3]
mov bx,1000H
mov ds,bx
mov ax,ds:[0] 一个字型数据 ax 是一个16位寄存器
mov ax,ds:[1]
mov ax,ds:[2]
mov ax,ds:[3]
mov ds:[0],ax
mov ds:[1],ax
mov ds:[0],al
mov ds:[1],ah
;===========================================================================
通过观察和思考 去猜测 设计者 为什么设计,积累了足够多的知识
debug u r t d e 假设 验证
数据长度? 字节型数据 字型数据 2byte
一个字型数据 存放在内存中 可以由 2个连续的地址的内存单元组成
高地址 内存单元存放 字型数据的 高位字节
低地址 内存单元存放 字型数据的 低位字节
机器码 汇编指令 在内存中的排列
b8 20 4e mov ax,4E20H 字型数据 高位字节 低位字节
05 16 14 add ax,1416H
bb 00 20 mov bx,2000H
01 d8 add ax,bx
89 c3 mov bx,ax
01 d8 add ax,bx
b8 1a 00 mov ax,001AH
bb 26 00 mov bx,0026H
00 d8 add al,bl
00 dc add ah,bl
00 c7 add bh,al
b4 00 mov ah,0
00 d8 add al,bl
04 9c add al,9C
0 20H
1 4EH
2 12H
3 00H
问题3.1
地址0 中存放的 字节型数据 是多少? 20H
地址0 中存放的 字型数据 是多少? 4E20H 4EH是高位 字节 20H 低位字节
地址2 中存放的 字节型数据 是多少? 12H
地址2 中存放的 字型数据 是多少? 0012H 00是高位字节 12 H 是低位字节
地址1 中存放的 字型数据 是多少? 124EH 12H是高位字节 4EH 低位字节
一个字型数据 存放在内存中 可以由 2个连续的地址的内存单元组成
高地址 内存单元存放 字型数据的 高位字节
低地址 内存单元存放 字型数据的 低位字节
;========================================================================================================
承上启下
寄存器
数据寄存器
地址寄存器 段地址寄存器 偏移地址寄存器
AX
BX 也可以被当作位 偏移地址寄存器
CX CX 也有其他作用
DX AX DX 用来处理数据的
通用寄存器
AX = AH + AL
BX = BH + BL
CX = CH + CL
DX = DH + DL
16位寄存器 可以各自分割为 2个 互相独立的 8位寄存器
翻译工作 为了保证 数据与寄存器之间的 位数一致性 寄存器的位数来判断
mov 移动指令
add 运算指令
运算时 有可能会 超过 寄存器 表示最大值 , 存放到其他地方去了
寄存器之间是 互相独立
地址寄存器
段地址寄存器 : 偏移地址寄存器 组合规则 组合起来
ds sp 段地址×16 + 偏移地址 = 物理地址
es bp 8086CPU 有20根地址线
ss si
cs di
ip
bx
CPU 是如何区分指令和数据的
CS IP 这2个寄存器
在任意时刻 CPU将 段地址寄存器CS 和 偏移地址寄存器IP 所组合出来的地址 从中读取的内容
全部当作 指令来 执行
指令是有长度的 IP寄存器 有关
可以修改 CS IP 这2个寄存器的 指令
转移指令
jmp 2000:0
jmp 寄存器格式
call xxxxx 指令执行的过程 =》 改变了的IP 保存了起来 跳转
;1, CPU从CS:IP 所指向的内存单元读取指令, 存放到 指令缓存器中.
;2, IP = IP + 所读指令的长度,从而指向 下一条指令。
;3, 执行指令缓存器中的内容,回到步骤1
内存中
寄存器(访问内存) 就是 讲解这个问题 可以推理出来的东西
指令和数据 存放在内存中是没有任何区别的
是我们汇编程序员 通过修改 寄存器中内容 地址寄存器 数据在哪里 指令在哪里
;=========================================================================================================
实验任务
1,使用debug,将上面的程序段写入内存,逐条执行,观察每条指令执行后,CPU中相关寄存器中内容的变化
可以使用 e 指令 和 a 指令修改
CPU如何区分指令和数据
机器码 汇编指令
b8 20 4e mov ax,4E20H
05 16 14 add ax,1416H
bb 00 20 mov bx,2000H
01 d8 add ax,bx
89 c3 mov bx,ax
01 d8 add ax,bx
b8 1a 00 mov ax,001AH
bb 26 00 mov bx,0026H
00 d8 add al,bl
00 dc add ah,bl
00 c7 add bh,al
b4 00 mov ah,0
00 d8 add al,bl
04 9c add al,9C
2,将下面3条指令写入 从2000:0 开始的内存单元中,利用这3条指令计算2的8次方
mov ax,1
add ax,ax
jmp 2000:0003
3,向内存 从 B8100H 开始的内存单元中填写数据
-e B810:0000 01 01 02 02 03 03 04 04
B810H*10H + 0 = B8100H
B800H*10H + 100H = B8100H
4,查看内存中的内容
PC机主板上的ROM中写有一个生产日期,在内存 FFF00H ~ FFFFFH 的某几个单元中,
请找出这个生产日期并试图改变它
DOS系统
;=============================================================================================================
debug 调试工具
r 可以查看,和改变寄存器中的内容
d 可以查看 内存中的内容
u 可以将 内存中的机器指令翻译成 汇编指令
a 可以以汇编指令的格式在 内存中写入一条汇编指令
t 执行 当前 CS:IP 所指向的机器指令
e 可以改写 内存中的内容
ASCII 编码 数字符号 英语字母 标点符号
ASCII 编码 ASCII 编码 所代表的字符
用计算机中的一个数字 去表示 一个 字符
48 alt
;==========================================================================================================
检测点 2.3
下面3条指令执行后,CPU几次修改IP?都是在什么时候?最后IP中的值是多少?
mov ax,bx => 存放到指令缓存器中 => 1 => 执行 ax = bx
sub ax,ax => 存放到指令缓存器中 => 1 => 执行 ax = 0
jmp ax => 存放到指令缓存器中 => 1 => 执行 1 IP = 0
ax = ax - ax
4
0
;==========================================================================================================
1, CPU从CS:IP 所指向的内存单元读取指令, 存放到 指令缓存器中.
2, IP = IP + 所读指令的长度,从而指向 下一条指令。
3, 执行指令缓存器中的内容,回到步骤1
;==========================================================================================================
1, CPU从CS:IP 所指向的内存单元读取指令, 存放到 指令缓存器中.
2, IP = IP + 所读指令的长度,从而指向 下一条指令。
3, 执行指令缓存器中的内容,回到步骤1
汇编指令 jmp jump
转移指令,可以修改CS 和IP 这2个寄存器 决定了CPU 从哪里读取指令
jmp 2000:0
jmp 寄存器
用到的时候 再说
1,假设 CS = 2000H ,IP = 0000 写出下列指令的执行的过程
a 2000:0 CS = 2000H IP = 0
mov ax,6622H CS = 2000H IP = 0 + 3 = 3
jmp 1000:3 CS = 2000H IP = 3 + 5 = 8
mov cx,ax
a 1000:0 CS = 1000H IP = 3
mov ax,0123H
mov ax,0 CS = 1000H IP = 3 + 3 = 6
mov bx,ax CS = 1000H IP = 6 + 2 = 8
jmp bx CS = 1000H IP = 8 + 2 = 10(A)
mov cx,0
1, CPU从CS:IP 所指向的内存单元读取指令, 存放到 指令缓存器中.
2, IP = IP + 所读指令的长度,从而指向 下一条指令。
3, 执行指令缓存器中的内容,回到步骤1
;==================================================================================
指令是有长度的 一条指令可以由多个字节构成
指令的执行过程
1, CPU从CS:IP 所指向的内存单元读取指令, 存放到 指令缓存器中.
2, IP = IP + 所读指令的长度,从而指向 下一条指令。
3, 执行指令缓存器中的内容,回到步骤1
实现一个功能
-a mov ax,1000H +3
mov bx,1000H
mov dl,10H
IP寄存器和 指令长度的关系就可以了
;==========================================================================================================
机器码 汇编指令
b8 20 4e mov ax,4E20H
05 16 14 add ax,1416H
bb 00 20 mov bx,2000H
01 d8 add ax,ax
89 c3 mov bx,ax
01 d8 add ax,bx
b8 1a 00 mov ax,001AH
bb 26 00 mov bx,0026H
00 d8 add al,bl
00 dc add ah,bl
00 c7 add bh,al
b4 00 mov ah,0
00 d8 add al,bl
04 9c add al,9C
将上面的机器码 用e 指令 输入到 2000:0 这个位置
内存 也是内存 翻译成汇编指令 被当作指令来使用
指令和数据在内存中有区别吗? 是没有区别的
CPU 中的CS 段地址寄存器 和 IP 这个 偏移地址寄存器 组合的时候 从中读取内容 当作指令来执行
CS IP 决定了 CPU 从哪里开始读取指令
;=========================================================================
全部当作数据 内存中
CPU 读取的时候
r
在内存 指令和 数据有区别吗? cs ip 指向的
CS IP 这2个寄存器 决定了 CPU 从哪里读取指令
;==================================================================================================
将他们当作数据
修改 cs 和ip
r
CS IP 这2个寄存器 决定了 CPU 从哪里读取指令
;==========================================================================================================
u指令 将某个内存地址 开始的字节 全部当作 指令
d指令 将某个内存地址开始的字节 全部当作数据
段地址寄存器 和 偏移寄存器
IP寄存器和 指令有关
dosbox -r
-r ds es ss cs
8086CPU中 在任意时刻,CPU将CS:IP 所指向的内容 全部当作指令来执行
在内存中 指令和数据 是没有任何区别的。都是二进制信息,CPU 只有 在工作的时候 才将有的信息当作 指令
有的信息 当作 数据,CPU根据什么将内存中的信息 当作指令的话,CPU 将 CS:IP指向的内存单元中的内容当作 指令。
;=============================================================================================================
检测点 2.2
段地址为 0001H 仅仅通过变化偏移地址寻址, CPU的寻址范围 为 _______ 到 _______
有一个数据存放在内存 20000H 单元中,现在给 段地址 为 SA , 若想用偏移地址寻找到此单元,则SA应该满足的条件是
最小_____ 最大 ______
提示 反过来思考一下,当段地址给多少时,CPU 无论怎么改变偏移地址 都无法找到 20000H
段地址×10H + 偏移地址 = 物理地址
0001H*10H
10H + (0 ~ FFFFH) = 物理地址
10H + 0 = 10H
10H + FFFFH = 1000FH
SA*10H + (0 ~ FFFFH) = 20000H
SA*10H + 0 = 20000H
20000H / 10H = 2000H SA = 2000H 2000H * 10H + 0 = 20000H
SA*10H + FFFFH = 20000H
-FFFFH = - FFFFH
SA*10H = 10001H
10001H / 10H = 1000H SA = 1001H 1000H * 10H + FFFFH = 1FFFFH
;=========================================================================================================
第一张只能填3位数字的纸条 第二张只能填3位数字的纸条 物理地址
210×10 726 2826
220×10 626
230×10 526
240×10 426
250×10 326
260×10 226
270×10 126
280×10 26
190×10 926 2826 - 1900
180×10 0 ~ 999
永远无法找到 最终的 物理地址
d 段地址:偏移地址
物理地址 段地址 偏移地址
21F60H 2000H×10H 1F60H
2100H×10H 0F60H
21F0H×10H 0060H
21F6H×10H 0000H
1F00H×10H 2F60H
1000H×10H ????
物理地址
段地址×10H + 偏移地址(0 ~ FFFFH) = 物理地址 1000*10H + FFFFH = 10000 + FFFF = 1FFFFH
;===============================================================================================
AX = AH + AL
BX = BH + BL
CX = CH + CL
DX = DH + DL
数据寄存器 地址寄存器
段地址寄存器:偏移地址寄存器
ds sp
es bp
ss si
cs di
ip
bx
0000 0000 0000 0000
1111 1111 1111 1111
8086CPU 给了 它 20根地址线 0000 0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111 0 ~ FFFFFH
地址线的数量 决定了 CPU 的寻址能力
地址加法器 地址的计算方式
段地址 × 16(10H) + 偏移地址 = 物理地址
段地址 × 16 = 基础地址
基础地址 + 偏移地址 = 物理地址
段地址 偏移地址
F230H×10H C8H = F23C8H
学校 体育馆 图书馆
0m 2000m 2826m
从学校 怎么去 图书馆
从学校直接走 2826 m 就可以到 图书馆了 物理地址
你先走2000m 到 体育馆 再走826m 到 图书馆 (2826m)
2000m + 826m = 2826m
基础地址 偏移地址 物理地址
现在 只能 通过 2张 只能写 3位数字的纸条 告诉你怎么去图书馆
你将第一张 纸条中的数字 × 10 + 第二张纸条中的数字 = 图书馆
200(段地址) * 10 = 2000m(基础地址)
826 偏移地址
2826 物理地址
8086CPU 就是这么一块 只能提供 写3位数字纸条的 CPU
;=========================================================================================
检测点2.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
只能使用目前学过的汇编指令,最多使用4条指令,编程计算2的4次方 2*2*2*2 = 16
mov ax,2
add ax,ax
add ax,ax
add ax,ax
mov al,2
add al,al
add al,al
add al,al
;=================================================================================================
AX = AX + 8
做实验,看一下加法超过寄存器的最大值会怎么样
编译器
dosbox -debug -a
mov ax,18H
mov ah,78h
add ax,8 16位加法
mov bx,ax
add ax,bx 16位加法
mov ax,0
mov ax,93H
add al,85H 8位寄存器 进行8位运算 保存8位数据
mov ax,0
mov al,93H
add ax,85H 16位加法 寄存器是 互相独立的 AL 就是AL AH 就是AH 不会互相影响
16位寄存器 进行16位运算 保存16位数据
mov ax,4E20H
add ax,1406H
mov bx,2000H
add ax,bx
mov bx,ax
add ax,bx
add al,100H
add ax,10000H
add al,bx
;================================================================================================
观察
编译 翻译工作
dosbox -debug -a
mov ax,5
mov ax,0 16位的0
mov al,5
mov ax,4E20H
mov bx,ax
mov ch,bl
mov cl,bh
mov dl,ch
mov ax,dx
数据与寄存器之间要 保证一致性 8位寄存器 给 8位寄存器 8位数据 给 8位寄存器 16位数据 给16位寄存器
mov ax,bl
mov bh,ax
mov al,100H
mov ax,10000H
mov al,0005H
这里只是移动指令,那么我们对数据进行处理比如加法 超过了al,或者ax 表示的最大值 怎么办? 下一节课说
;======================================================================================================
AX
BX
CX
DX
因为它们有一个特殊的地方 是其他寄存器 所没有的
通用寄存器,存放数据的,数据寄存器 箱子是有容量的 16位寄存器
1byte = 8bit
2byte = 16bit 0000 0000 0000 0000 ~ 1111 1111 1111 1111 0 ~ FFFFH 0 ~ 65535 65536
AH AL
它们可以各自分割为 2个8位寄存器
AX = AH + AL AX 的高8位构成 AH寄存器 H = high
BX = BH + BL AX 的低8位构成 AL寄存器 L = low
CX = CH + CL
DX = DH + DL
0000 0000 ~ 1111 1111 0 ~ FF 0 ~ 255 256
为了兼容
8086CPU 8位寄存器 为了保证 以前编写的程序 稍加修改 就可以 运行在8086CPU上 为了兼容
内存的最小单元? 字节 8bit
CPU从内存中读取一个 字节 8bit 字节型数据 8位数据 -> 8位寄存器中
数据线呢?16根数据线 数据线的 宽度决定了 CPU 一次性 能够 读取 多长的数据
8086CPU一次性可以 处理 2种尺寸的数据
字节型数据 byte 8bit - 8位寄存器中
字型数据 2byte = 16bit - 16位寄存器中 2个字节
一个字节是 这个字型数据的 高位字节(AH,BH,CH,DH) 还有一个字节是 这个字型数据的 低位字节(AL,BL,CL,DL)
什么是8位数据 16位数据
什么是8位寄存器 16位寄存器
;=========================================================================================
导言 目录
1,基础知识
2,寄存器
3,寄存器(内存的访问) debug 查找错误的工具
编程 访问内存空间
4,第一个程序
5,[BX]和loop指令
6,包含多个程序段
7,更灵活的定位内存地址的方法
8,数据处理的两个基本问题 实验7
9,转移指令的原理
10,CALL 和 RET 指令 课程设计一
11,标志位寄存器 ;承上启下的意思 必须要有个 寄存器 去判断某些 事情
12,内中断
13,int指令
通过端口改变 内存空间中的内容
14,端口
15,外中断
16,直接定址表
17,使用BIOS进行键盘输入和磁盘读写 课程设计二
18,综合研究 汇编语言和C语言的关系
;======================================================================================
承上启下的作用
内存地址去访问的
RAM 断电后 指令和数据就没有了 允许读取和 写入
ROM 断电后 指令和数据还存在 只允许 读取
GPU 怎么办? 图形处理芯片 很久 以前是没有的
图形的要求越来越高了 分工 早期 画图这个工作 也是 CPU 做的
GPU 分工 进行 图形处理
有专门的编程语言 去 编程 物理知识 和 数学知识
B800:0000 400 当作显存就可以
汇编语言 针对 CPU 的
CPU中的什么呢
地址线 数据线 控制线
CPU中一定有可以存放 地址信息 和数据 信息的地方 寄存器
我们汇编程序员 就是 通过 汇编语言 中的 汇编指令 去 修改 寄存器中的内容
从而 控制 CPU 就可以 控制整个计算机 了
MOV AX,0005 AX 就是 一个数据寄存器 地址寄存器
DS ES SS CS 都是 冒号左边的 一种 地址信息 IP 比较像
修改寄存器中 内容 控制CPU
启发
;======================================================================================
鼠标
键盘
音箱
麦克风
CPU 也是通过内存地址去 访问 鼠标键盘 。。。 不是的
端口的东西 port 港口 装货和卸货 数据
拆过鼠标和键盘
都有一块芯片 同样也能存储指令和数据
CPU 是一块芯片 存储指令和数据
端口
端口号的东西 60H 就是端口号
input out 和端口有关 读取 写入 控制线 读写信息
mov
CPU 可以通过 主板上电路 读到 所有的数据
CPU 就像人的大脑一样
主板 是人体的骨骼
主板上的电路是什么 ? 是附加在骨骼上的 神经
大脑得到反应 CPU 得到数据
计算机 电脑
;======================================================================================
内存 内存条 主内存
e B800:400 回车
1空格 1空格
2空格 2空格
...
e 修改内存地址中的内容
内存地址 是不是 内存条的 内存地址? 明显不是
计算机有很多部件。内存条是计算机的一个部件,显卡 显存 插在主板上 显示器和主板
感性认识
RAM 允许读取和写入 断电后 指令和数据就丢失了
ROM 只允许读取 断电后 指令和数据还存在 一般用在 启动计算机上面
通过 内存地址 去访问
1, CPU和计算机各个部件之间的关系? 内存条 显卡(显存) 给他们编号
2, 什么是RAM内存?
3. 什么是ROM内存?
;=========================================================================================
1 byte = 8 bit
1 KB = 1024byte 2的10次方byte
1 MB = 1024 × 1KB 2的10次方byte 1MB = ? byte 2的20次方byte
1 GB = 1024 × 1MB 2的20次方byte 1GB = ? byte 2的30次方byte
数轴一样
检测点1.1
1个CPU的寻址能力为 8KB , 那么他的地址总线宽度为 ________ 8×1024 8192 0000 0000 0000 0000 0
1111 1111 1111 1111 1
1KB的存储器有 _________ 存储单元的编号从 _____ 到 _______ 1024 0 ~ 1023
1KB的存储器可以存储 ______bit, ______Byte 1024 × 8 1024
1GB,1MB,1KB 分别是 ______Byte 2的30次方byte 2的20次方byte 2的10次方byte
8080,8088,80286,80386的地址总线宽度分别为 16根,20根,24根,32根 则他们的寻址能力分别为 _____KB,____MB,_____MB _____GB
64KB 1MB 16MB 4GB
8080,8088,8086,80286,80386的数据总线宽度分别为 8根,8根,16根,16根,32根,则它们依次可以传送的数据为 ____B ___B ___B ___ B ___B 1 1 2 2 4
从内存中读取1024字节的数据,8086至少要读 ___次 80386 至少要读取 ____次 512 256
在存储器中,数据和程序(指令)以 ____形式存放 二进制 十六进制 阅读方便 debug
;============================================================================================
地址线 决定了 CPU的 寻址能力
数据线 决定了 CPU的 和其他部件 进行数据传送时 一次性能够 传送 多少字节 的能力
控制线 决定论 CPU 对 其他部件 进行控制的能力
字节 1byte = 8bit 8个 二进制位
传送2个字节
;========================================================================================
CPU 中存放了 一部分指令和数据
内存 内存条中 内存条 是内存的一部分
指令和数据在内存中是没有任何区别的
CPU 要从 内存条 中 读取指令和 数据 怎么做? 写入 放回到内存中
拆机箱
CPU 和 内存条 都是 插在一块 电路板上的 主板 电路
CPU 和内存条 之间 进行联系 需要通过 这些电路
表示三种意思
内存编号信息 地址线 内存地址 电路 其实是一种 导线
数据信息 数据线
读写信息 控制线
电路 能表示什么状态? 高低电平 0 或者 1
只有一根地址线 物理上限制住了
地址线的数量 决定了 你能够找到多大的地址
寻址能力 规律
10根 2的10次方 1024 地址 0000 0000 00 ~ 1111 1111 11 0 ~ 1023
推理一边
1, 内存编号为什么是从0开始的? 物理上的限制 电路 只能表示 0 或者 1 00000
2, 什么叫寻址能力? 地址线的数量 决定了 你能传多少 0或者1 决定了 你能够找到多大的地址
;========================================================================================
内存编号 十六进制数字 一些英语单词的简写 + 一些数字
汇编指令存放在哪里? CPU 存放
100w条汇编指令 存放在哪里?
内存 内存条 主内存 绝大多数 指令和数据 都是存放在 内存条中的
0123456789 ABCDEF 10H
DOSBOX -debug -u -d
u指令和d指令的 解释不同
u指令我们看到的 是 机器指令 和 汇编指令
d指令 我们看到的是 数据
同一串 十六进制数字 产生了 2种解释 指令 数据
内存的最小单元是什么
74H 03H E9H 一个字节 = 2个十六进制位 = 8个2进制位 0111 0100
1byte = 8bit 1bit = 1个2进制位 0 1 1
计量单位 光年 星系与星系之间 差多少多少公里?
1byte = 8bit
1KB = 1024byte k = kilo b = byte
1MB = 1024KB m = million b = byte
1GB = 1024MB g = giga
1,机器指令(汇编指令)和数据存放在哪里? 内存
2,机器指令和(汇编指令)是以什么形式存放在内存中的? 二进制 方便我们人类阅读
3,内存(存储单元)它的编号是怎么算的? 0123456789....
4,内存的计量单位?
;=============================================================================================
观察
计算机是由什么驱动? 电
光有电? 机器 由很多部件组成 组织在一起运行 指令 告诉它这里怎么做 那里怎么做
机器指令 01010101010101 B
CPU的部件 中央处理器
将一串二进制数字 转换成高低电平 驱动计算机运行
01010101010101
01010101010101
01010101010101
01010101010101
DOSBOX -debug -u
相同的一串十六进制数字:某种编号 十六进制数字 一些英语单词的简写 + 一些数字
汇编指令
74 03 JZ 0105
0111 0100 0000 0011 机器指令
E9 97 00 JMP 019C
1110 1001 1001 0111 0000 0000
B8 05 00 MOV AX,0005
1011 1000 0000 0101 0000 0000
MOV move 移动
将0005 移动到 一个叫做 AX的箱子
英语单词简写
更贴近人类的思维
翻译软件
编译器
汇编语言
1,汇编指令 通过编译器 也就是翻译软件 翻译成 机器指令 机器码
2,伪指令 告诉编译器 也就是翻译软件 你这里怎么翻译 那里怎么翻译
3,符号体系 +-*/ 编译器管
感性认识
A = 10
B = 11
C = 12
D = 13
E = 14
F = 15
1,什么是机器指令? 010101010101
2,机器指令由谁执行? CPU
3,机器指令和汇编指令有什么关系? 通过编译器 也就是翻译软件 汇编指令 可以翻译成 机器指令
4,什么是编译器? 翻译软件
5,什么是伪指令? 告诉翻译软件 这里怎么翻译 那里翻译
;=============================================================
十六进制 和 二进制 之间 快速互相转换(重要)
16 -> 10 -> 2
2 -> 10 -> 16
用4个2进制位 去表示一个 16进制位
通过观察
;======================================================
十进制 快速转换成 十六进制
凑 16的倍数
;===================================================
十六进制 八进制
十进制 进位
二进制
'0123456789' ABCDEF
A = 10
B = 11
C = 12
D = 13
E = 14
F = 15
57 H
57
01001010101B
十进制转换成二进制
一个数字 除以 2 只可能 产生 0 或者1 的余数
推理出 一种新的计算方式 观察 思考
1 = 有 0 = 无 数轴 和 位的概念
通过观察 获得 的优势
;===================================================
十进制
'0123456789'
二进制
'01'
每一个数字 在每一个位的上 所代表的意义并 不相同
11110011
;======================================================
'0123456789'
十进制 -> 位的概念 -> 二进制
每个一个数字 在每一个位上 所代表意义 并不相同