微型计算机接口技术课后习题

0x01 Pentium保护模式存储管理

1.1

简述虚拟存储器的含义,试在存储层次,功能,结构,信息传送单位,操作过程等方面对比虚拟存储器和Cache存储器。

  • 虚拟存储器是由主存储器,辅助存储器,辅助硬件和操作系统管理软件组成的一种存储体系
  • 其目的是为了增加存储器的容量,速度接近于主存储器,单位造价接近辅助存储器

虚拟存储器和Cache存储器对比.png

1.2

简要说明虚拟存储器的工作原理

  • 应用程序访问虚拟存储器时,给出逻辑地址。然后进行内部地址变换得到物理地址,若要访问的信息在主存中,则访问主存储器,得到信息;若访问的信息不再主存中,则根据逻辑地址进行外部地址变换得到辅存地址;同时检查主存是否有空闲区,若无则根据替换算法将主存中某个块送到辅存,再把辅存地址中的信息块送到主存;若有,则直接送入主存。

1.3

虚拟存储器指的是主存-辅存存储层次,它给用户提供了一个比实际空间大得多的空间。

  • 物理
  • 虚拟

1.4

说明3类地址空间的含义。

  • 虚拟地址空间,是程序员用来编写程序的地址空间,其对应的地址称为虚地址或逻辑地址。
  • 主存地址空间,是实存地址空间,是存储,运行程序的空间,其相应的地址称为主存物理地址或实地址。
  • 辅存地址空间,是磁盘存储器的地址空间,是用来存放程序的空间,器地址称为辅存地址或磁盘地址。

1.5

段描述符按段的性质分为哪几类?

  • 分为3类,程序段描述符,系统段描述符,门描述符。

1.6

Pentium的实地址方式和保护模式由__寄存器的PE位来选择。

  • CR0

1.7

段描述符高速缓冲寄存器有什么作用?

  • 段描述符高速缓冲寄存器即段寄存器。其作用如下。
  • CS,存放正在运行的程序代码的段基址
  • DS,存放数据段的段基址
  • SS,存放当前堆栈段的段基址
  • ES,存放附加的数据段的段基址

1.8

说明向保护模式转换的方法及转换前的准备工作

  • 初始化IDT,使其包含至少32种中断类型有效的中断门描述符
  • 初始化GDT,使其第0项为一个空描述符,并且至少包含一个数据段描述符,一个代码段描述符,一个堆栈段描述符。(为什么?orz :question:

1.9

Pentium微处理器的虚拟地址有多少位?虚拟地址的2个组成部分分别叫什么名字?

  • 46位
  • 段选择符;段内偏移量

1.10

Pentium微处理器的保护机制有哪些措施?

  • 任务间存储空间的保护
  • 段属性和界限的保护
  • 特权级保护

1.11

Pentium微处理器是怎样将虚拟地址转换成物理地址的?

  • 在实地址模式下,虚拟地址的形式为[段地址]:[偏移地址],物理地址是这样形成:段寄存器内容左移4位加上偏移地址。
  • 在保护模式下,虚拟地址的形式为[段选择符]:[偏移地址],物理地址是这样形成:段选择符在段寄存器中,但是并不直接表示段基址,通过段选择符部分的13位索引字段确定段描述符再段描述符表的位置,取出段描述符中的32位段基址与偏移量相加得到线性地址,若不启用分页则线性地址作为物理地址。

1.12

试说明Pentium微处理器段的转换过程

  • 我们不妨以访问数据段的访问过程来说明段的转换过程,其他段类似

  • 现在有一个虚地址,由段选择符和段内偏移构成

  1. 将16位的段选择符送入DS
  2. 根据段选择符中TI的值决定选择再局部描述符表LDT还是选择再全局描述符表GDT来寻找段描述符;由于二者类似,不妨假设选择LDT。
  3. 段选择符中的INDEX字段乘8后加上LDTR中的基地址得到LDT中的数据段描述符的地址。
  4. 将对应的段描述符的内容送入DS段寄存器的不可见部分,其中包括32位基地址,20位段限,12位属性。
  5. DS段寄存器32位基地址与虚地址中的段内偏移向加得到线性地址。

1.13

试说明数据段描述符与代码段描述符的异同点。

  • 段描述符的格式相同,都属于程序段描述符

  • TYPE类型字段不同,D/B字段表示含义不同

1.14

IDTR,GDTR,LDTR分别代表什么寄存器,其内容是什么信息?有什么作用?

  • 中断描述符表寄存器;全局描述符表寄存器;局部描述符表寄存器
  • IDTR保存着32位基址和16位界限; GDTR保存着GDT的32位基地址和16位界限;LDTR保存着16位选择符,32位基地址,20位界限,12位属性组成。
  • 作用
    • IDTR:32位基址表示IDT起始位置,16位界限表示IDT的描述符项数
    • GDTR:32位基址表示GDT起始位置,16位界限表示GDT的描述符项数
    • LDTR:32位基址标识LDT在内存中的起始物理地址,20位界限表示LDT的长度,而16位段选择符是指向GDTLDT描述符的选择符,需要从GDT中读取段描述符,并且装入LDTR中程序不可见部分。才能找到LDT

1.15

Pentium可进行段页式存储器管理。Pentium的段描述符为8字节,包括了段基址,段长和属性等信息(段基址32位,段长20位),其中有一个G位用于定义段长单位,G=0定义段长以字节为单位,G=1定义段长以页面为单位,针对Pentium,分析回答以下问题:

  1. 一个页面包含多少个字节?其页面数据容量是否可变?若可以改变,则简要说明改变的方法。
  2. 当G=0时,该段的最大数据容量是多少个字节?
  3. 当G=1时,该段的最大数据容量时多少个字节?

0x03 中断

3.1

什么叫中断?在微机系统中为什么要使用中断?

  • CPU在正常执行当前程序,由某一事件引起CPU暂时停止当前任务,转去执行请求CPU暂停的服务程序,该服务程序执行完后又返回继续执行被暂停的程序,这一过程叫中断
  • 主要作用
    • 实现主机与I/O设备的并行工作
    • 利用中断进行实时处理
    • 利用中断方式进行人机对话
    • 故障处理
    • 多处理机系统中各处理机之间协调作用

3.2

什么叫中断源?中断嵌套的含义是什么?

  • 凡是能够提出中断请求的设备或异常故障均被称为中断源
  • 在执行中断服务程序的过程中又发生新的中断

3.3

Pentium微处理机内部有哪几类中断源?简要说明各类的特点是什么?

  • 分为四类中断
    • 可屏蔽中断INTR
    • 非屏蔽中断NMI
    • 软件中断(执行INTO,INT3,INT n,BOUND指令引起的中断)
    • 异常
  • INTR通常是由Intel 8259A中断控制器驱动,向INTR引脚发中断请求,通过数据总线向CPU发中断类型码
  • NMI通常用来通知CPU发生重大故障的事件,比如电源掉电。不受IF中断允许标志的影响,优先级非常高。上升沿触发信号
  • 软件中断
    • 人为设置在程序中
    • 类型码包含在指令中,所以不执行中断响应总线周期
    • BOUND指令外,中断返回地址为下一条指令
  • 异常是在CPU执行一条指令过程中出现的错误或者检测的异常情况产生的

3.4

Pentium微处理机中中断和异常有何异同?

  • 中断是用来处理CPU以外的异常事件
  • 异常时用来处理执行指令期间由CPU本身检测出来的某些异常事情作出的响应

3.5

通常CPU响应外部中断的条件有哪些?

  • 有中断请求
  • 中断标志位IF=1

3.6

简述CPU响应中断后,中断处理的过程,用流程图表示

Pentium实模式下中断处理过程

3.7

什么情况下需要有中断判优机构?程序查询式和中断向量式2种中断源识别与判优方案各有什么特点?

  • 系统遇到多个中断源同时请求中断的情况下,需要有中断判优机构。
  • 程序查询式是软件查询,较为灵活,但是中断源多时,转至中断服务程序时间长
  • 中断向量式是硬件优先级排队电路确定优先级,速度块,但是优先级固定不变。

3.8

什么叫中断向量?试说明Pentium微处理机可屏蔽硬件中断是怎样获得中断向量,从而进入中断程序的。

  • 中断向量是中断服务程序的入口地址。

  • 根据8259A送道数据总线的中断类型码*4取得中断向量,把中断向量的前2个字节装入IP,后2个字节装入CS,这样CPU执行的下一条指令就是中断服务程序的第一条指令,也就是说,CPU进入了中断服务程序。

3.9

中断描述符表的作用是什么?其内保存的是什么信息?

  • 中断描述符表保存门描述符
  • 门描述符中保存的信息有段选择符,32位偏移,还有属性用来在GDT或LDT中找到中断服务程序的基地址。

3.10

8259A芯片是一种什么类型的芯片?试着说明8259芯片的主要功能。

  • 是一种中断管理芯片,简称PIC
  • 主要作用
    • 管理8级优先权中断源
    • 对任何级别中断源可单独屏蔽
    • 向CPU发送可编程的标识码,即中断类型码
    • 可与Pentium的CPU直接连接,不需要外加电路
    • 多种工作方式

38

INTRNMI的区别

  • CPU在响应NMI时,不从外部设备读取中断类型码,因为NMI的中断类型码固定为2

OS习题

0x01

1

什么是操作系统?操作系统有哪些特点?

  • 操作系统是位于硬件层之上,所有其他系统软件层之下的一个系统软件,通过它管理系统中的各种软件和资源,使它们能被充分利用,方便用户使用计算机系统。

  • 特点

    • 并发性
    • 共享性
    • 异步性
    • 虚拟性

2

硬件将处理器划分为两种,即管态和目态,这样做会给操作系统的设计带来什么好处?

  • 防止用户侵入系统,起到保护系统的作用

3

何为特权指令?试举例说明。如果允许用户进程执行特权指令,会带来什么后果?举例说明

  • 特权指令:只能在管态下才能执行的指令称为特权指令
  • 允许用户进程执行特权指令,则可能会导致停机,影响其他程序允许,甚至整个系统

4

中断向量在计算机中的存储位置是由硬件决定的,还是由软件决定的?

  • 是由硬件决定的

5

中断向量的内容是由操作系统决定的还是由用户程序决定的?

  • 是由操作系统决定的

6 为什么??

中断向量内的处理器状态字应当标明为管态还是目态?为什么?

  • 应标明为管态
  • 处理机状态由目态转为管态的唯一途径是中断,因此会产生中断向量,此时需要把中断向量的处理器状态字标明为管态。

7

系统如何由目态转换为管态?如何由管态转换为目态?

  • 唯一途径是中断
  • 修改程序状态字PSW

8

中断与程序并发之间的关系是什么?

  • 中断时程序并发的前提条件,若没有中断,操作系统则不能获得系统控制权,无法对处理器重新分配。

9

根据用途说明“栈”和“堆”的差别?

  • 栈用来实现中断嵌套和子程序调用的参数,返回断点,局部变量,返回值
  • 堆是为动态变量分配存储空间

10

何谓系统栈?何谓用户栈?系统栈有何用途?用户栈有何用途?

  • 系统栈在逻辑上属于操作系统空间,是系统空间中的一个区域。
  • 用户栈属于用户空间,是内存中用户空间的一个区域。
  • 系统栈用途:一是保存操作系统子程序间相互调用的返回点,参数,局部变量,返回值;二是中断响应时保存中断现场
  • 用户栈用途:一是保存用户函数调用时的返回点,参数,局部变量,返回值。

11

为何无法确定用户堆栈段的长度?

  • 用户堆栈段的长度取决于

    • 进程子程序嵌套深度
    • 子程序的参数和局部变量的数量和类型
    • 动态变量的数量和类型

    这些在进程运行前无法确定,导致堆栈段的长度无法预先确定。

12

为何堆栈段的动态扩充可能导致进程空间的变迁?

  • 堆栈段的扩充意味着存储区域的增加,并要求与原来存储区域连续。若原存储处可扩展区域被其他进程所占用,可能需要将整个进程空间搬迁到另外一个区域,从而导致了进程空间的变迁。

13

何谓并行?何谓并发?在单处理器系统中,下述并行和并发信息哪些可能发生,哪些不会发生?

  1. 进程与进程之间的并行
  2. 进程与进程之间的并发
  3. 处理器与设备之间的并行
  4. 处理器与通道之间的并行
  5. 通道与通道之间的并行
  6. 设备与设备之间的并行
  • 并行指的时在微观上的同时,在绝对的同一时刻由多个进程同时向前推进
  • 并发不需要微观上的同时,只需要从宏观上看多个程序都在向前推进
  • 不可能发生:(1)

14

何谓作业?它包括哪几个部分?各个部分的用途时什么?

  • 用户要求计算机系统为其完成的计算任务的集合称为作业
  • 作业包括
    • 程序
    • 作业说明书
    • 数据
  • 程序是完成某一功能
  • 数据是程序处理对象
  • 作业说明书用来说明作业处理的步骤

15

试述批处理操作系统与分时操作系统的区别

  • 批处理操作系统是以脱机操作为标志的操作系统,作业逐批进入系统,逐批离开系统。无用户干扰
  • 分时操作系统是以联机操作为标志的操作系统,适合程序的动态修改。需要与用户交互

16

从透明性和资源共享2个方面说明网络操作系统与分布式操作系统的差别。

  • 从透明性来看,网络操作系统用户能感觉到本地HOST与非本地HOST在地理额外i之上的差异;而在分布式系统中,所有HOST构成一个完整的,功能更加强大的计算机系统,掩盖了地理位置上的差异
  • 从资源共享来看,分布式操作系统比网络操作系统更能共享更多的资源,原因在于网络操作系统其HOST上的系统不统一,导致一个计算任务不能由另外一台HOST运行,但是分布式操作系统的HOST操作系统相同。

17

为什么构成分布式系统的主机一般都是相同的或兼容的?

  • 利于进程的动态迁移

18

集群系统与分布式系统有何差异?

  • 集群指的是将几台服务器集中在一起,实现同一业务。
  • 分布式是将不同的1业务分布在不同地方
  • 分布式结构的每一个节点都可以做集群;而集群并不一定就是分布式

19

何谓云存储?何谓云计算?

0x02

1

为何引入多道程序设计?在多道程序系统中,内存中的作业的道数是否越多越好?请说明原因。

  • 因为系统的资源数量多,资源使用者少。为了允许多个程序同时进入系统,即增加资源使用者的数量,提高系统资源利用率。
  • 不是,一个计算机系统的资源是有限的,只能容纳适量的作业;当作业道数不合理增加,导致资源竞争大,系统开销大。

2

多道程序设计会带来哪些问题?如何解决?

  • 处理器资源管理问题,需要实现处理器资源在各个程序之间的分配和调度。
  • 内存资源管理问题,解决:程序使用相对地址,不使用绝对地址,实现程序的重定位,还需要防止程序之间的内存干扰
  • 设备资源管理问题,操作系统需要采取适当的分配策略据此对资源加以管理。

3

什么是进程?进程具有哪些主要特性?试比较进程与程序之间的相同点与不同点。

  • 进程是具有一定独立功能的程序关于一个数据集合的一次运行活动
  • 进程的特性
    1. 并发性
    2. 动态性
    3. 独立性
    4. 交互性
    5. 异步性
    6. 结构性
  • 程序是构成进程的组成部分之一
  • 程序是静态的,进程是动态的;程序是永久的,进程是具有生存周期的;一个程序可以对应多个进程,一个进程只能对应一个程序。

4

有人说,用户所执行的程序一定是用户自己编写的。这种说法对吗?如果不对,试举例说明之。

  • 不对,比如C编译程序时以用户进程身份进行,但C编译程序不是用户自己编写的。

5

什么是进程上下文?进程上下文包括哪些成分?哪些成分对目态程序是可见的?

  • UNIX System V中,将进程的物理实体与支持进程运行的物理环境合称为进程上下文。
  • 包括3个组成部分:
    • 用户级上下文
    • 系统级上下文
    • 寄存器上下文
  • 用户级上下文和部分寄存器上下文对目态程序是可见的。

6

进程一般具有哪三个主要状态?举例说明状态转换的原因

  • 运行态;就绪态;等待态
  • 当就绪态进程获得处理器,变为运行态
  • 当运行态进程被剥夺处理器,变为就绪态
  • 当运行\就绪态进程因为某一事件受阻时,变为等待态
  • 当等待事件发生,变为就绪态

0x03

例3-1

考虑CPU阵发进程,得到先到先服务算法调度性能指标

  1. 甘特图
  2. 列表

例3-2

最短作业优先算法

SVM

我们知道

逻辑回归激励函数

激励函数

本质上,支持向量机的代价函数与逻辑回归的代价函数无差别,但是为了使得后面计算更直观些,我们不妨稍微调整一下支持向量机的代价函数。

  • 回顾逻辑回归代价函数

  • 而支持向量机代价函数

    其中,C可以理解为$\frac{1}{\lambda}$

而SVM也被人们称之为大间距分类器。

大间距分类器

即,使得间距最大。

  • 核函数

Kernels

设存在2个特征,我们设其假设函数为

再进行一些优化

高斯核函数

  • 根据$x$的各个特征选取landmarks

核函数

那么

不妨再重新回顾下过程

  1. Given

  2. Choose

  3. Get $f_i$

  4. 对于$x_{(i)}$

对于参数

  • C
    • Large C: Lower bias, high variance
    • Small C: Higher bias, low variance
  • $\sigma^2$
    • Large $\sigma^2$: Higher bias lower variance
    • Small $\sigma^2$: Lower bias higher variance

计数方法

二项式定理

  • 对称关系
  • 递推关系Pascal公式
  • 单峰性

牛顿二项式

设有$\dbinom{a}{r}$

  1. 当$a=-n$

多项式定理

设$n$为正整数,则

  1. 其展开式在合并同类项后不同项目数目为$\dbinom{n+t-1}{n}$

组合恒等式

  • page 55: 6

中断

bx,si,di,bp

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    assume cs:code
    code segment
    start:
    mov ax,cs
    mov ds,ax
    mov si,offset sqr
    mov ax,0
    mov es,ax
    mov di,200h
    mov cx,offset sqrend-offset sqr
    cld
    rep movsb

    mov ax,0
    mov es,ax
    mov word ptr es:[7ch*4],200h
    mov word ptr es:[7ch*4+2],0

    mov ax,4c00h
    int 21h

    sqr:
    mul ax
    iret

    sqrend:
    nop

    code ends
    end start

汇编实验

0x01

从键盘输入一系列以$为结束符的字符串,然后对其中的非数字字符计数,并显示出计数结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
assume cs:code
data1 segment
DB "Please input the word !",0dh,0ah,0

data1 ends

data segment

db 10 dup (0)
data ends

ANS segment
DB 0dh,0ah,"answer=",0
ANS ends

stack segment
db 128 dup (0)
stack ends
code segment
start:

mov ax,stack
mov ss,ax
mov sp,128

mov ax,data1
mov ds,ax
mov cx,19h
mov bx,0
call show_str

mov dx,0
s2:
;counter save in dx


a1:
mov ah,1
int 21h
cmp al,'$'
jne a2

mov ax,ANS
mov ds,ax
mov cx,7
mov bx,0
call show_str
mov cx,dx
jcxz Q2
call show

Q1:
mov ax,4c00h
int 21h
Q2:
mov dl,'0'

mov ah,2
int 21h
mov ax,4c00h
int 21h


a2:
cmp al,'1'
jb a3
cmp al,'9'
ja a3

jmp a1
a3:
inc dx
jmp a1


;input: ds,bx
;using bx,cx,dx
show_str:
push ax
push dx
push bx
push cx
mov dh,0
s11:

mov DL,[BX]
mov cx,dx
jcxz zero
mov ah,2
int 21h
inc bx
loop s11
zero:
pop cx
pop bx
pop dx
pop ax
ret
;-------------------------------------------------------------------------






;input: dx
;output [data to string and show the string]
show:
push ax
push bx
push ds
push si
push dx
push cx

mov ax,dx
mov bx,data
mov ds,bx
mov si,0
call dtoc

mov ax,data
mov ds,ax
mov bx,0
call show_str

pop cx
pop dx
pop si
pop ds
pop bx
pop ax
ret
;--------------------------------------------------------------------------------




; input ax
; output translate the ax to string and save in the data from offset data:0000h
dtoc: push ax
push si
push di
push dx
push bx
push cx
mov di, 0
mov dx, 0
mov bx, 10

devide: mov cx, ax
jcxz stop
div bx
inc di
push dx
mov dx, 0
jmp devide
stop: mov cx, di
string: pop bx
add bx, 30h
mov [si], bl
inc si
loop string

pop cx
pop bx
pop dx
pop di
pop si
pop ax
ret

code ends
end start

0x02

定义一个字变量DAT1,长度为1,把DAT1中的数据按字节单元依次显示到屏幕上,显示方式为 段地址:偏移量 十六进制字节数据.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
assume cs:code

data1 segment
DAT1 DW 1234H
data1 ends

data segment
dw 128 dup (0)
data ends
stack segment
dw 128 dup (0)

stack ends
code segment
start:

mov ax,stack
mov ss,ax
mov ax,128
mov sp,ax
mov ax,data
mov ds,ax
mov ax,data1
mov es,ax
mov bx,0

mov ax,0
mov si,ax
mov ax,4
mov di,ax
mov ax,data1
call dtoc16
mov ax,'h'
mov ds:[4],ax
mov ax,':'
mov ds:[5],ax
mov ax,0
mov si,6
call dtoc16
mov al,'h'
mov ds:[10],ax

mov al,' '
mov ds:[11],ax

mov si,12
mov di,2
mov al,es:[0]
mov ah,0
call dtoc16
mov al,0dh
mov ds:[14],al
mov al,0ah

mov ds:[15],al
mov ax,data1
mov di,4
mov si,16
call dtoc16
mov al,'h'
mov ds:[20],al
mov al,':'
mov ds:[21],al
mov ax,1
mov di,4
mov si,22
call dtoc16
mov ds:[26],'h'
mov ds:[27],' '
tes:
mov si,28
mov di,2
mov al,es:[1]
mov ah,0

call dtoc16











call show_str


mov ax,4c00h
int 21h








;input
;ax: as the data to string
;ds: segment address in the memory to save string
;si: the begin of offset address in the memory to save string
;di: how many byte to use
dtoc16:
push ax
push bx
push cx
push dx

mov bx,16
mov cx,4
;devide16:
s:
mov dx,0
div bx
push dx

loop s
mov cx,di
cmp cx,2
jne string
pop ax
pop ax
string:
pop ax
add ax,30h
mov ds:[si],al
inc si
loop string

pop dx
pop cx
pop bx
pop ax
ret




show_str:
push ax
push dx
push bx
push cx
mov dh,0
s11:

mov DL,[BX]
mov cx,dx
jcxz zero
mov ah,2
int 21h
inc bx
loop s11
zero:
pop cx
pop bx
pop dx
pop ax
ret



code ends
end start

0x05

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
assume cs:code
code segment
mov ax,0B800H
mov ds,ax
mov bx,0
mov si,0
mov cx,16
mov al,'W'
mov ah,01110100B
s:
mov ds:[bx+si],ax
inc ah
add bx,160
add si,2



loop s

mov ax,4c00h
int 21h

code ends

0x06

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
assume cs:code
stack segment
dw 128 dup (0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,128
mov ax,0B800H
mov ds,ax
mov bx,158+158
mov si,0
mov cx,20
mov al,' '
mov ah,01000100B

s1:
push cx
mov bp,bx
mov di,si

mov cx,2

;清屏
call Clear_Screen
s2:
push cx

mov cx,9
s3:
mov ds:[bp+di],ax

add di,2
loop s3

pop cx
add bp,158
mov di,si

loop s2
mov dl,'O'
mov dh,00000100B
mov ds:[bp+si],dx
mov ds:[bp+si+16],dx

pop cx
add si,2

loop s1

mov ax,4c00h
int 21h
Clear_Screen:
push ax
MOV AX,0003H
INT 10H
pop ax
ret
code ends
end start

寻址法方式

bx,si,di,bp

  • 8086CPU中,只有4个寄存器再用[…]`来进行内存的寻址。

  • 可以使用4个寄存器单独出现,亦或,bx+si,bx+di,bp+si,bp+di

  • 若使用bp,那么段地址默认为ss

  • 若使用bx,那么段地址默认为ds

  • 数据在哪

    • CPU内部
    • 内存
    • 端口
  • 数据多长

    • 寄存器指明数据尺寸

    • 若无寄存器,则有word ptrbyte ptr指明,比如

      1
      mov word ptr ds:[0],1
    • 有些指令默认了数据尺寸,比如push只进行字操作。

Example 1

  • 子程序
    • ret
    • call
    • 现场保存:stack
  • 跳转
    • jmp
    • jcxz
  • how to show on the screen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
assume cs:code
data segment
db 'Welcome to masm!',0
data ends

stack segment
dw 16 dup (0)
stack ends

code segment
start:
mov dh,8
mov dl,3
mov cl,2
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,32
mov si,0

call show_str
mov ax,4c00h
int 21h



show_str:
push ax
push cx
push dx
push ds
push si

mov ah,0
mov al,dh
mov dh,160
mul dh
mov bx,ax;save the row

mov ah,0
mov al,dl
mov dl,2
mul dl
mov cx,ax;save the column
mov di,cx

mov ax,0b800h
mov es,ax

mov si,0
mov al,cl
s:
mov cx,0
mov cl,ds:[si]
jcxz q

mov ch,al
inc si
mov es:[bx+di],cx
add di,2
jmp s




q:
pop si
pop ds
pop dx
pop cx
pop ax
ret
code ends


end start

Example2

  • 进行不会产生溢出的除法运算
  • 其中cx存余数,dx存高16位商,ax存低16位商
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
assume cs:code
stack segment
dw 16 dup(0)
stack ends

code segment
start:
mov ax,stack
mov ss,ax
mov sp,32
mov ax,4240h
mov dx,000fh
mov cx,0ah
call divdw
mov ax,4c00h
int 21h

divdw:
push bx
mov bx,ax
mov ax,dx
mov dx,0
div cx
push ax
mov ax,bx
div cx
mov cx,dx ;保存余数
pop dx;得到高位的商



pop bx
ret


code ends


end start

Example3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
assume cs:code
stack segment
dw 16 dup(0)
stack ends
data segment
db 10 dup(0)
data ends

code segment
start:
mov ax,12666
mov bx,data
mov ds,bx
mov si,0
call dtoc

mov dh,8
mov dl,3
mov cl,2
call show_str

mov ax,4c00h
int 21h
dtoc:
push ax
push si
mov bx,10
s1:
mov dx,0
div bx
mov cx,ax
jcxz q1
add dl,30h
mov ds:[si],dl
inc si
mov ax,cx
jmp s1
q1:
mov dl,0
mov ds:[si],dl
inc si
pop si
pop ax
ret


show_str:
push ax
push cx
push dx
push ds
push si

mov ah,0
mov al,dh
mov dh,160
mul dh
mov bx,ax;save the row

mov ah,0
mov al,dl
mov dl,2
mul dl
mov cx,ax;save the column
mov di,cx

mov ax,0b800h
mov es,ax

mov si,0
mov al,cl
s:
mov cx,0
mov cl,ds:[si]
jcxz q

mov ch,al
inc si
mov es:[bx+di],cx
add di,2
jmp s




q:
pop si
pop ds
pop dx
pop cx
pop ax
ret






code ends


end start

Debug环境设置

0x01 前期准备

  • 安装DOSBox

  • 设置盘符

  • image-20200514154924432.png

    当出现了-_的闪烁符号时候说明我们成功进入了debug中。

0x02 命令介绍

以下所有命令均在debug模式下输入,即-_,并且,每一种命令不会导致控制寄存器指令指针IP的移动。

  • 需要注意的是,Instruction Pointer存放下一次要取出指令的偏移地址(假设您没有直接指定地址)
  • CS:IP指示下一条要取出的指令的实际地址。
  • IP不能由程序直接存取,由BIU来修改(BIU是什么???
命令 作用
R 观看或修改寄存器的值
H 计算两个16进制数的和与差
D 显示内存区域的内容
E 改变内存单位的内容
F 使用指定值填充内存
M 将指定内存区域的数据复制到指定地址
C 比较两块内存的内容
S 搜索指定串
A 输入汇编命令
G 执行汇编指令
U 对机器代码反汇编
N 设置文件名,将汇编程序进行存盘
W 将文件写入磁盘
L 读入内存
T 执行汇编程序,单步跟踪
P 执行汇编程序,单步跟踪,但不会跟踪子程序或软中断
I 从计算机输入端口读取数据
O 向计算机输出端口输出数据
Q 回到DOS状态
  • 可用Ctrl+S来暂停屏幕输出

以下转载

R命令的使用

R命令作用:观看和修改寄存器的值。

在提示符“-”下输入以下命令:R。DEBUG将会显示出当前所有寄存器和标志位的状态。

接下来再输入命令RCX。在提示符“:”后输入100。该命令的作用是将寄存器CX的值设置为100(注意:DEBUG使用的是十六进制,这里的100相当于十进制的256。)

最后再执行R命令,观看修改后的寄存器值。

H命令的使用

H命令作用:计算两个十六进制数的和与差。

在提示符“–”下输入以下命令:H 10 1。观看命令执行结果。

运行结果的前一个数是计算出来的和,后一个数是计算出来的差。计算结果均用十六进制形式表示。

D命令的使用

D命令作用:显示内存区域的内容。

在提示符“–”下连续执行命令R、D、D。观看命令执行结果。

前面已经介绍过了,命令R的作用是显示当前寄存器的值。而命令D的作用是显示内存区域的内容,最左边是内存的起始地址,中间以十六进制的形式显示内存值,最右边是以ASCII码的形式显示内存值。每行最多显示16个字节的内容。

命令D可以带参数也可省略参数。设DEBUG启动时DS的值为X,当省略参数时,命令D显示内容以X:100为起始,每次显示128个字节的内容。以后再执行不带参数的命令D时,DEBUG将按上次的位置接着显示下去。

带参数时DEBUG能够显示指定地址范围的内容。带参数的方式有三种:

方式一:d [起始位置]。DEBUG从起始位置开始显示128个字节的内容。在提示符“-”下执行命令D 1AF5:100。观看命令执行结果。

方式二:d [起始位置] [结束位置]。DEBUG从起始位置开始一直显示到结束位置。在提示符“-”下执行命令D DS:100 1FF。观看命令执行结果。

方式三:d [起始位置] [L长度],长度以L参数为标识。DEBUG从起始位置开始显示指定长度的内容。在提示符“-”下执行命令D DS:100 L10。观看命令执行结果。

E命令的使用

E命令作用:改变内存单位的内容。

E命令的使用方式为:E [起始位置]。

在提示符“-”下输入以下命令:E 1AF5:100。

DEBUG首先显示[1AF5:0000]的内容00.,这时可以修改该字节的值。如果还要修改后续的内容,可以按空格键继续。当要跳过某个字节时,可以按连续的两个空格跳到后一个字节去。

F命令的使用

F命令作用:使用指定的值填充指定内存区域中的地址。

F命令的使用方式为:F [范围] [填充列表]。

在提示符“-”下输入以下命令:F 1AF5:100 L20 1 2 3 4 5。执行命令D 1AF5:100观看命令执行结果。

说明:该命令是用字节序列01、02、03、04、05轮流填充从1AF5:100开始长度为20H的内存区域。

在提示符“-”下输入以下命令:F 1AF5:100 13F 41 42 43 44。

说明:该命令是用字节序列41、42、43、44轮流填充从1AF5:100开始一直到1AF5:13F的内存区域。

M命令的使用

M命令作用:将指定内存区域的数据复制到指定的地址去。

M命令的使用方式为:M [范围] [指定地址]。

在提示符“-”下输入以下命令:M 1AF5:100 13F 1AF5:140。执行命令D 1AF5:100观看命令执行结果。

C命令的使用

C命令作用:将两块内存的内容进行比较。

C命令的使用方式为:C [范围] [指定地址],意思就是将指定范围的内存区域与从指定地址开始的相同长度的内存区域逐个字节进行比较,列出不同的内容。

在提示符“-”下输入以下命令:C 1AF5:100 13F 1AF5:140。由于两块内容完全相同,所以命令执行后没有任何显示。

在提示符“-”下输入以下命令:C 1AF5:100 107 1AF5:180,比较的区域长度为8个字节。命令执行后列出比较结果不同的各个字节。

S命令的使用

S命令作用:在指定的内存区域中搜索指定的串。

S命令的使用方式为:S [范围] [指定串]。

在提示符“-”下输入以下命令:D 1AF5:100 11F。显示该区域的内存值。

在提示符“-”下输入以下命令:S 1AF5:100 11F 41 42 43 44。搜索该区域是否存在字节串41 42 43 44,并将搜索结果一一列出。

从执行结果可以看出,总共搜索到八处。

A命令的使用

A命令作用:输入汇编指令。

以下的程序要在屏幕上显示“ABCD”四个字符。

首先用E命令将“ABCD$”四个字符预先放在内存CS:200处,然后执行A100命令输入汇编程序代码:

MOV AX,CS

MOV DS,AX

MOV DX,200

MOV AH,9

INT 21

INT 20

(说明:前两行汇编指令用于将段寄存器CS的值赋给段寄存器DS。第三到第五行汇编代码的作用是显示以“$”为结尾的字符串。最后一行用于结束程序。

G命令的使用

G命令作用:执行汇编指令。

G命令的使用方法是:G [=起始地址] [断点地址],意思是从起始地址开始执行到断点地址。如果不设置断点,则程序一直运行到中止指令才停止。

在设置完示例九的的内存数据并且输入完示例九的程序后运行这些汇编代码。在DEBUG中执行命令G=100,观看运行结果。

汇编程序运行后在屏幕上显示出“ABCD”四个字符。

接下来在DEBUG中执行G=100 10B,意思是从地址CS:100开始,一直运行到CS:10B停止。观看运行结果。

命令执行后,不但显示出字符串“ABCD”,而且列出当前寄存器和标志位的值。

U命令的使用

U命令作用:对机器代码反汇编显示。

U命令的使用方法是:U [范围]。如果范围参数只输入了起始地址,则只对20H个字节的机器代码反汇编。执行命令U100,观看反汇编结果。

执行命令U100 10B,观看反汇编结果。该命令的作用是对从100到10B的机器代码进行反汇编。

N命令的使用

N命令作用:设置文件名,为将刚才编写的汇编程序存盘做准备。

以下的DEBUG命令序列作用将刚才的汇编程序存为磁盘的COM可执行程序。

D200 20F

U100 10C

N E:\FIRST.COM

RCX

:110

W

第一和第二条命令的作用是检查一下刚才编写的汇编指令。第三条命令的作用是设置存盘文件名为E:\FIRST.COM,第四条命令的作用是设置存盘文件大小为110H个字节。最后一条命令是将文件存盘。

文件存盘后执行E:\FIRST.COM,观看存盘的可执行文件的运行效果。

W命令的使用

W命令作用:将文件或者特定扇区写入磁盘。

在示例“N命令的使用”中已经实验了如何使用W命令将文件存盘。

在没有很好地掌握汇编语言和磁盘文件系统前,暂时不要使用W命令写磁盘扇区,否则很容易损坏磁盘文件,甚至破坏整个磁盘的文件系统。

L命令的使用

L命令作用:从磁盘中将文件或扇区内容读入内存。

将文件调入内存必须先用DEBUG的N命令设定文件名。以下例子是将E:\FIRST.COM读入内容。

N FIRST.COM

L

观看调入程序的汇编代码可以使用DEBUG的U命令,用U100观看调入的COM文件。

读取磁盘扇区的方式是:L [内存地址] [磁盘驱动器号] [起始扇区] [扇区数]。“内存地址”指定要在其中加载文件或扇区内容的内存位置,如果不指定“内存地址”的话,DEBUG将使用CS寄存器中的当前地址。“磁盘驱动器号”指定包含读取指定扇区的磁盘的驱动器,该值是数值型:0=A,1=B,2=C等。“起始扇区”指定要加载其内容的第一个扇区的十六进制数。“扇区数”指定要加载其内容的连续扇区的十六进制数。

只有要加载特定扇区的内容而不是加载文件时,才能使用[磁盘驱动器号] [起始扇区] [扇区数]参数。

例如:要将C盘第一扇区读取到内存DS:300的位置,相应的DEBUG命令为L DS:300 2 1 1。但是由于Windows操作系统对文件系统的保护,这条命令可能会被操作系统禁止运行。

T命令的使用

T命令作用:执行汇编程序,单步跟踪。

T命令的使用方式是T [=地址] [指令数]。如果忽略“地址”的话,T命令从CS:IP处开始运行。“指令数”是要单步执行的指令的数量。

以下示例对E:\FIRST.COM进行单步跟踪。

N E:\FIRST.COM

L

U100 10B

R

T=100

T

第一、二条命令是装入文件,第三条命令是列出程序反汇编代码,第四条命令是显示当前寄存器值,第五条命令是从CS:100处开始单步跟踪,第六条命令是继续跟踪后续的指令。

P命令的使用

P命令作用:执行汇编程序,单步跟踪。与T命令不同的是:P命令不会跟踪进入子程序或软中断。

P命令的使用方式与T命令的使用方式完全相同。

I命令的使用

I命令作用:从计算机输入端口读取数据并显示。

I命令的用法是I [端口地址]。例如从3F8号端口读取数据并显示的命令为:I 3F8。这里不对该命令做解释。

O命令的使用

O命令作用:向计算机输出端口送出数据。

O命令的用法是O [端口地址] [字节值]。例如向278号端口发出数据20H的命令为:I 278 20。这里不对该命令做解释。

Q命令的使用

Q命令的作用是退出DEBUG,回到DOS状态。