Skip to main content

80X86:Assembly

·1451 words·7 mins· loading · loading ·
Table of Contents

汇编语言复习
#

​ 1.这是某学校汇编语言的课程内容,简单做一个复习的笔记,如果能帮到校友就更好了……

​ 2.整体来看感觉内容不多,但是很杂很乱,容易一开始让人很不知所以然,再加上讲课老师感觉逻辑性不算很强,可能让人感觉有点劝退,但是这门课程本身还是相当重要的……

​ 3.然后就是关于本课程的实验,我的评价就是善用AI,如果你觉得很难写,但是前提是你先要看得懂并且会用MASM工具来调试。

​ 4.手写代码占30分,这个要卷的话看下上机作业,不卷随缘,剩下基本都是八股。

​ 5.我的笔记确实复制粘贴了很多PPT,但是哪怕是PPT你也会想看带目录的对么……

​ 6.关于考试,我整理了一个文件,存放了两个往年题,并且我个人的考试经验来看,第二套往年题目相当具有参考价值,点击这里下载。最后一道关于I/O的编程题目几乎是类似的,没有答案,你直接截图给某个GPT就可以了。

第一章 基础
#

第一章只有一些基本的概念。

执行过程
#

image-20250504204325331

二进制数:计算机硬件唯一识别和使用的数制 以2为基的数制表示法,数由2个数字构成(0、1),二进制数后缀为B, 如10110111B。 十进制数:人类自然语言中常用的数制 以10为基的数制表示法,数由10个数字构成(09),十进制数后缀为D, 如1945D。 十六进制数:程序设计中方便使用和转换的数制 以16为基的数制表示法,数由16个数字构成[09、A(10)、B(11)、 C(12)、D(13)、E(14)、F(15)],十六进制数后缀为H,如 18ADH。

进制的转换
#

image-20250504204803342

数码的表示
#

1.原码表示法
#

(1)原码表示法: 将数的真值形式中的正(负)号,用代码0(1)来表示,数 值部分用二进制来表示。符号 + 绝对值 正数:符号位为0,后面的n-1位为数值部分 负数:符号位为1,后面的n-1位为数值部分 (2)原码的特点 “0” 的原码有两种表示法 [+0]原=00000000B, [-0]原=10000000B n位二进制原码所能表示的数值范围为: -(2n-1-1)~(2n-1-1)

原码表示一个数时,最高位为符号位

[+3]原码 = 0 000,0011 = 03H [-3]原码 = 1 000,0011 = 83H [+0]原码 = 0 000,0000 = 00H [-0]原码 = 1 000,0000 = 80H

2.反码表示法
#

正数的反码同原码,负数的反码数值位与原码相反 例:n=8bit [+5]反码 = 0 000,0101 = 05H [-5]反码 = 1 111,1010 = FAH [+0]反码 = 0 000,0000 = 00H [-0]反码 = 1 111,1111 = FFH 0的表示不唯一

3.补码表示法
#

(1)补码表示规则: 正数的补码: 符号 - 绝对值(与正数的原码相同) [+1]补码 = 0000 0001 = 01H [+127]补码 = 0111 1111 = 7FH [+0]补码 = 0000 0000 = 00H 负数的补码: 负数 X 用 2n-|X| 表示 [-1]补码 = 28-1 = 1111 1111 = FFH [-127]补码 = 28-127 = 1000 0001 = 81H 一种简单方法: (1)写出与该负数相对应的正数的补码 [-1]补=1111 1111 [+1]补= 0000 0001 (2)按位求反1111 1110 (3)末位加1

image-20250504210649399

第二章 80x86计算机组织
#

2.1 三种模式
#

实模式-虚拟8086模式-保护模式

image-20250321153928618

*2.2 寄存器(Register):
#

image-20250321154148066

数据寄存器
#

(暂态计算中用到的寄存器)

image-20250321154402434

AH(high) AL(low)

AX(adder) BX(base) CS(counter) DX(double)

指针寄存器
#

指针和变址寄存器用来引用一些数据:能够存放偏移量

image-20250321154536511

SP(stack pointer)

BP(base pointer)

SI(source) DI(destination)

段寄存器
#

在存储器中用分段的方式来管理数据,存放了很多base地址。

image-20250504212541554

CS(code segment) SS(stack segment) DS(data segment) ES(append segment)

控制寄存器
#

image-20250504213006364

IP(Instruction pointer)—》指令地址的偏移量

flags有哪些,什么意思?

标志位分类 ➢ 条件(状态)标志 OF、SF、ZF、AF、CF和PF,其值取决于一个操作完成后,算逻部件ALU所处的状态。 ➢ 控制标志和系统标志 DF、IF和TF,其值是通过指令人为设置的,用以控制程序的执行。

image-20250505221928271

陌生的flag寄存器:

image-20250505222044170

image-20250505222141095

*2.3 存储器
#

◆ 计算机存储信息的基本单位是一个二进制位 ◆ 8086字长为16位,地址长度20位 ◆ 80386以上机的字长为32位,地址长度32位以上

怎么表示?

image-20250505222618323

​ Little Endian:小端法,03080H是低的地址,存到低位的字节,03081H是高位的地址,就存放到高位的字节,这里是重点。

存储器采用分段管理后,一个内存单元地址要用段基地址和偏移量两个逻辑地址来描述,表示为:

段基址:偏移量

就是要理解分段的机制。

存储器分段:段起始地址必须是某一小段的首地址,段的大小可以是64K范围内的任意字节。 **物理地址:**每个存储单元的唯一的20位地址。 段基地址:段起始地址(20位)=10H * 段寄存器(16位) —-》在二进制上左移动了4个bit 偏移地址:段内相对于段起始地址的偏移量(16位),偏移量又称为有效地址(EA)物理地址 = 16d * 段寄存器 + 偏移地址 = 10H * 段寄存器 + 偏移地址

image-20250505223724463

几个段? 4个。

image-20250505224206839

中间比较复杂的部分都是操作系统的内容,可以暂时不管。

第三章 指令系统和寻址方式
#

3.1 80X86寻址方式 3.2 80X86机器语言指令概况 3.3 80X86指令系统

3.1 怎么寻找地址?
#

寻址方式:指令指定操作数地址的方式 1、与操作数据有关的寻址方式 2、与转移地址有关的寻址方式

操作数通常保存在: (1) 指令中MOVAX, 2000H (2) CPU的寄存器中MOVAX, BX (3) 内存单元中MOVAX, [2000H] (4) I/O接口寄存器中INAH, 20H

3.1.1 与数据有关的寻址方式
#

经常拿来改错。

还会考察你什么形式是怎样的寻址方式。

image-20250508232002768

image-20250505225609356

image-20250505225632252

image-20250505225901716

[]间接引用地址,相当于引用,在内存中取地址。

作用:

  1. 不加 []:直接数值或地址

mov al, VALUE

如果 VALUE DB 66H:不加中括号,会被解释为立即数 66H

编译后等同于:

mov al, 66h

⚠️ 但在某些上下文中可能错误,比如你写:

mov ax, VALUE ; VALUE 是 DB 类型,而 AX 是 16 位寄存器 → 错误!

  1. 加 []:访问内存地址中的内容

mov al, [VALUE]

现在 VALUE 被当作一个内存地址,意思是:

    “从地址为 VALUE 的内存中取出一个字节的值,放到 AL 里”

假如:

VALUE DB 66H

则执行完之后:AL = 66H

这是直接寻址方式(Direct Addressing)。

image-20250505230407588

怎么来做偏移?

image-20250506195353369

EA的计算方法:重点

image-20250506195735294

要注意的表示方式。

缺省的时候默认就是DS数据段。

MOV BX,[2100H];DS:[2100H] →BX

image-20250506200550592

容易混淆的地方:

用 VALUE DB 10 定义了一个变量,那么VALUE是这个定义的变量的内存地址的符号名(指针)

MOV AX,VALUE 符号不对应。

data segment
value db 66H
other db 88H
arr db 12h, 34h, 56h, 78h
data ends

code segment
mov ax, data
mov ds, ax

mov al, value
mov cl, [value]
mov ax, word ptr value
mov bx, word ptr [value]
...
code ends
指令 正确性 说明
mov al, value 默认等价于 mov al, [value]
mov cl, [value] 显式间接寻址,读取一个字节
mov ax, word ptr value ⚠️ 虽然合法,但读取了 valueother 两个字节
mov bx, word ptr [value] ⚠️ 同上,低地址是 value,高地址是 other

image-20250506202340610

image-20250506202631093

都差不多。

base pointer 和 stack segment(SS)来做配合处理。

◼ 只要指令寻址时使用了BP,计算物理地址时约定段是SS段。 ◼ 指令寻址时使用了除BP以外的其它寄存器,计算物理地址时约定段为DS段。

3.1.2 和转移地址相关的方式
#

image-20250506203925217

寻找地址的方式,因为可能会转移到别的CS段中去。

段内寻址:转移指令与转向的目标指令在同一代码段中CS内容不变,IP内容修改 段间寻址:转移指令与转向的目标指令在两个代码段中CS和IP内容修改 直接寻址:转向的目标指令地址由转移指令直接指明

间接寻址:转向的目标指令地址由转移指令中的寄存器或存储单元内容给出

1.段内直接寻址
#

相当于给IP直接加上此时两个位置的地址之间的差值。

image-20250506210312441

2.段内间接寻址
#

两张PPT可以解决问题,实际上就是用offset做间接的取值。

image-20250506210903648

image-20250506211147423

注意这里的si是16位,也就是近转移。

例题:

image-20250506211523016

3.段间直接寻址
#

image-20250506211802872

这就是直接更改代码段的CS和IP的值来跳转。IP在CS上面。

4.段间间接寻址
#

image-20250506212009693

下面的图比较重要:

image-20250506212324349

条件转移指令只能使用段内直接寻址方式 无条件转移(JMP)和转子指令(CALL)可用四种方式的任何一种

3.2 80X86语言指令概况
#

不重要吧,对于考试。

3.3 80X86指令系统
#

3.3.1 数据传送指令
#

注意pushApopA,把所有的寄存器从stack上面进行移动。

image-20250506213227249

容易错的位置:

DS这样的段寄存器不能用立即数更改。

CS不能修改。

不能直接从内存到内存。

image-20250506213441507

MOVSX MOVZX 有符号和0扩展的区别,比较简单。

push 和 pop 指令

注意只能处理16bit和32bit的寄存器,不能POP AL!!!

注意栈顶位于低地址位置,当你push数据的时候,sp的值应该减少。

image-20250507185237782

pop是把stack里面的值拿出来放到DST里面去。

image-20250507190453576

image-20250507190629703

XCHG直接作交换

image-20250507190704209

注意操作数是32bit 还是 16bit,来决定SP的增减值的大小。

image-20250507190926322

IN OUT这里只能用于Adder寄存器。

I/O指令的输入和输出
#

输入和输出都是站在CPU的角度上对于端口。

image-20250507191450552

image-20250507191535239

image-20250507191919568

用AL寄存器接收来自于27H端口的数据。

地址传送指令

image-20250507224256941

image-20250507224330548

能同时改变两个寄存器的原始指令。

送给寄存器的同时还送给段寄存器。

低16bit给寄存器,高16bit给段寄存器。

很好的一个例子:

image-20250507224712179

类型转换指令
#

image-20250507225206221

image-20250507225321673

BSWAP:什么逆天指令?

3.3.2 算术指令
#

image-20250507225619830

1.加法指令(加法指令ADD、带进位加法指令ADC、加1指令INC等)
#

(1)加法指令 ADD

格式:ADD DST,SRC 功能:(DST)+(SRC)→ (DST) 说明:对操作数的限定同MOV指令 (2)带进位加法指令 ADC

多个字节或者多个字的时候用ADC处理。

格式: ADC DST,SRC 功能:(DST)+(SRC)+CF→(DST) 说明:对操作数的限定同MOV指令,该指令适用于多字节或多字的加法运算

(3)加1指令 INC 格式:INC OPR 功能:(OPR)+1 → (OPR) 说明:很方便地实现地址指针或循环次数的加1修改 (4)互换并加法指令 XADD(486以上)

和ADD一样,就是把SRC的值更换成了原来的DST。

格式:XADD DST,SRC 功能: (SRC) + (DST) → 暂存器 (DST) → (SRC) 暂存器→(DST) 说明:该指令执行后,原DST的内容在SRC中,和在DST中

image-20250507225948790

2.减法指令(减法指令SUB、带借位减法指令SBB、减1指令DEC、求补指令NEG、比较指令CMP等)
#

(1)减法指令 SUB 格式:SUB DST,SRC 功能:(DST)-(SRC)→(DST) 说明:除是实现减法功能外,其他要求同ADD (2)带借位减法指令 SBB 格式:SBB DST,SRC 功能:(DST)-(SRC)-CF→(DST) 说明:除了操作为减外,其他要求同ADC,该指令适用于多字节或多字的减法运算 (3)减1指令 DEC 格式:DEC OPR 功能:(OPR)-1→(OPR) 说明:可以很方便地实现地址指针或循环次数的减1修改

4)求补指令 NEG 格式:NEG OPR 功能:0FFFFH -(OPR)+1 → (OPR) 对目标操作数(含符号位)求反加1,并且把结果送回目标 说明:利用NEG指令可实现求一个数的补码 (5)比较指令 CMP

只改变FLAG,不更改实际的value.

格式:CMP OPR1,OPR2 功能:(OPR1)-(OPR2),只影响标志位,不影响源和目的操作数 说明:这条指令执行相减操作后只根据结果设置标志位,并不改变两个操作数的原值,其他要求同SUB。CMP指 令常用于比较两个数的大小。

image-20250507230302398

3.乘法指令 (无符号乘法指令MUL、带符号数乘法指令IMUL等)
#

image-20250507230533324

(1)无符号数乘法 MUL 格式: MUL SRC ; SRC:除立即数以外的寻址方式 功能: 字节操作: (AL) * (SRC) → (AX) 字操作: (AX) * (SRC) → (DX:AX) 双字操作: (EAX) * (SRC) → (EDX:EAX) 乘积的高一半为0,则CF、OF均为0,否则CF、OF均为1 这样可以检查结果是字节、字或双字。 (2)带符号数乘法 IMUL 格式: IMUL SRC ;SRC:除立即数以外的寻址方式 功能: 字节操作: (AL) * (SRC) → (AX) 字操作: (AX) * (SRC) → (DX:AX) 双字操作: (EAX) * (SRC) → (EDX:EAX) 乘积的高一半是低一半的符号扩展,则CF、OF均为0,否则CF、OF均为1。 其实质和MUL情况下一样,主要用于判断结果是字节、字或双字。

📌 DX 寄存器的常见用途
#
  1. *乘法和除法指令中用于存放高位结果
    • 如无符号乘法 MUL
      • 16 位乘法时:AX × SRC = DX:AX,结果的高 16 位在 DX
    • 除法时也是如此,例如 DIV
      • 被除数是 DX:AX 组成的 32 位数。
  2. 端口输入输出指令中存储端口号
    • 比如 IN AL, DX 表示从 DX 寄存器所指端口读取字节到 AL。
    • OUT DX, AL 表示将 AL 中的数据写入 DX 所指端口。
  3. 通用用途寄存器(可存储临时变量、地址、计数值等)

4.除法指令(无符号除法指令DIV、带符号除法指令IDIV)
#

image-20250508195631603

image-20250508195904796

考试大题会出一道类似于这样的手写代码,最好手写一遍,处理一些细节问题:怎样写出完整的可执行程序?

image-20250508200115555

5.十进制调整指令(DAA、DAS等)
#

懒的看,考了再说。。。。。。

3.3.3 逻辑指令
#

逻辑指令包括:

1.逻辑运算指令
#

字面意思,大概看看

image-20250508204434703

image-20250508204523132

2.位测试并修改指令
#

。。。。。。

3.位扫描指令
#

image-20250508205019710

。。。。。。

4.移位指令
#

image-20250508205120238

image-20250508205313600

注意:那么✖2或者➗2的幂之类的就用位移运算最好。

image-20250508205718751

3.3.4 串处理指令
#

处理存放在存储器里的数据串,所有串指令都可以处理字节或字,386及后继机型还可以处理双字。 利用串操作指令可以直接处理两个存储器单元的操作数,方便地处理字符串或数据块。 串处理指令包括: MOVS 串传送 CMPS 串比较 SCAS 串扫描 LODS 从串取 STOS 存入串 INS 串输入(从I/O端口输入) OUTS 串输出(向I/O端口输出)

image-20250508210214692

和MOV有什么区别?

image-20250508215507132

功能 MOV MOVS 系列
用途 常规数据传送 字符串/内存块复制
位置指定 显式指定源和目标 隐式使用 SI/ESI/RSIDI/EDI/RDI
可否用于循环 通常需要手写循环 可配合 REP 一条指令复制多次
是否影响 DF 不会 受方向标志位 DF 影响
image-20250508210709322

注意源和目标的要放入的寄存器的位置。

source:DS:[SI]/ES:[SI]

destination:ES:[DI]

image-20250508214850624

自动化的更改这些变量,注意每次移动的大小取决于数据类型的大小。

DF(direction flag) 决定复制的方向。

先不管REP REPZ之类的

3.3.5 控制转移指令
#

控制转移指令包括:

1.无条件转移指令
#

image-20250508215917083

具体情况:

image-20250508220228239

直接用位移量(相当于是利用EA的差值)或者间接用地址(直接利用EA)跳转。

这里会考试:

注意偏移量和位移量的区别。

image-20250508220525907

image-20250508220806340

段间CS IP的值都要进行更改。

2.条件转移指令
#
指令 条件 条件描述
JZ ZF = 1 上一条操作结果为 0(等于)
JNZ ZF = 0 不等于
JC CF = 1 有进位(Carry)
JNC CF = 0 无进位
JE 等于(其实和 JZ 一样)
JNE 不等于(= JNZ

image-20250508221019366

image-20250508221122247

image-20250508221234107

3.条件设置指令
#

image-20250509081349720

4.循环指令
#

80X86为了简化循环程序的设计,设计了一组循环指令如下: LOOP OPR LOOPE/LOOPZ OPR LOOPNE/LOOPNZ OPR

image-20250509081546022

1.只能短转移。

2.CX或者ECX作为计数器。

image-20250509081931320

LOOP 指令做简化

5.子程序调用/返回
#

子程序:子程序结构相当于高级语言中的过程(PROCEDURE).为便于模块化程序设计,往往把程序中某些具有独立功能的部分编写成独立的程序模块,称之为子程序。 程序中 由子程序调用指令调用子程序,而在子程序执行完后由返回调用指令返回调用程序继续执行。 80X86提供了以下指令 CALL子程序调用 RET子程序返回

根据调用的类型:对于CS和IP进行压栈的操作。

RET,就是恢复现场。

image-20250509082350043

image-20250509082602971

6.中断指令/返回
#

有时当系统运行或者程序运行期间在遇到某些特殊情况时,需要计算机自动执行一组专门的程序来进行处理。 这种情况称为中断,所执行的这组程序称为中断例行程序或中断子程序。 其它随机事件,如I/O控制和数据传送,不采用中断方式系统效率会很低。

注意和子程序调用的区别。

image-20250509083025153

image-20250509083202918

保存疑IP CS FLAGS

INT INTO IRET

硬中断就是被动的。

  1. 中断向量 ◼中断向量:中断处理子程序的入口地址 ◼在PC机中规定中断处理子程序为FAR型 ⚫ 每个中断向量占用4个字节,其中低两个字节为中断向量的偏移量部分,高两个字节为中断向量的段基址部分

  2. 中断类型号 IBM PC机共支持256种中断,相应编号为0~255,把这些编号称为中断类型号。

  3. 整个中断向量表就是指向一些code segment。

image-20250509083527717

256 * 4 = 1024bytes

0000H —》03FFH的内存单元。

调用和返回:

注意INT功能的过程,从中断向量表中取值。

image-20250509083910646

3.3.6 处理机控制指令
#

image-20250509084152759

比如在调用中断程序之前,STI,设置中断允许的标志位。

第四章 汇编语言程序格式
#

4.1 汇编程序功能
#

前面是linkerlab的内容。

机器指令 伪指令(前面的定义数据之类的) 宏指令

image-20250509084707063

4.2 伪操作
#

伪操作:告诉汇编程序的某些功能说明或定义,仅在汇编时使用,不会汇编成任何机器指令。

4.2.1 处理器选择伪操作
#

.386P

4.2.2 段定义伪操作
#

image-20250509092011916

image-20250509093102701

明确关系,主程序开始之前指定。

4.2.3 程序开始和结束伪操作
#

image-20250509093811386

NAME TITLE END

4.2.4 数据定义及存储器分配伪操作
#

到现在才讲数据段中怎样定义数据。

image-20250509094235468

看右边的具体例子。

image-20250509094518409

段基址 偏移量 类型

image-20250509095032153

image-20250509095134450

注意以下这个例子:偏移量和放置的问题。

image-20250509095427571

4.2.5 表达式赋值伪操作EQU
#

image-20250509095722323

知道是EQU就可以:

image-20250509095825252

4.2.6 地址计数器对准伪操作
#

image-20250509111802050

ORG 设置,可以达到对齐的效果。

4.2.7 基数控制伪操作
#

。。。。。。

4.3 汇编语言程序格式
#

image-20250509101356403

image-20250509101445137

考察过上述的定义。

image-20250509101809493

4.4 汇编语言程序上机过程
#

image-20250509102209066

返回DOS的方法。

MOV AX, 4C00H

INT 21H

第五章 循环与分支程序
#

应该是没有考察过画图的问题:

image-20250509102655541

看一个跳转的例子:

image-20250509103144957

5.1循环程序设计
#

具体的多看看例题,或者自己手写代码。

image-20250510131341606

image-20250510132206318

用CX控制循环的变量就可以。

image-20250510132716081

感觉右边的更好记忆。

5.2分支程序设计
#

主要看一下跳转表:

image-20250510132907361

5.3如何在实模式下发挥 80386及其后继机型的优势
#

。。。。。。

第六章 子程序调用(就是调用函数的准备)
#

6.1子程序的设计方法
#

image-20250510134210629

procedure name PROC NEAR/FAR

……

procedure name ENDP

子程序和调用者在不在同一个代码段之中,利用FAR NEAR

image-20250510134533590

比如:

FAR属性在同一个段或者不同的段内都可以调用

image-20250510134727205

段间调用压入CS寄存器:FAR属性和NEAR属性

image-20250321142045587

保护和恢复寄存器的方法

◼ 子程序开始时,使用PUSH指令保存 ◼ 子程序返回前,使用POP指令恢复 ◼ 保存和恢复次序应该相反

优先保存FLAG寄存器

参数传送:
#

​ (1)通过寄存器传送参数 ​ (2)通过存储器传送参数 ​ *子程序和调用程序在同一程序模块中,则子程序可 直接访问模块中的变量 ​ *子程序和调用程序不在同一程序模块中 ​ (3)通过地址表传送参数地址 ​ (4)通过堆栈传送参数或参数地址

寄存器传送
#

image-20250510140638026

大概看一下这段代码,同一个段中对于寄存器的访问都是相同的。

存储器直接访问
#

image-20250510141026189

传送一个table(地址表)
#

参数很多,用offset把很多参数的起始位置放到一张表里:

image-20250510141234000

直接压入堆栈
#

image-20250510143039900

类似于结构体的处理:
#

image-20250510143426185

怎么访问?

image-20250510143534988

6.4 *DOS系统功能调用
#

可能是考察重点。。。。。。

系统功能调用是DOS为系统程序员及用户提供的一组常用子程序。 用户可在程序中调用DOS提供的功能。 DOS规定用INT 21H中断指令作为进入各功能调用子程序的总入口,再为每个功能调用规定一个功能号,以便进入相应各个子程序的入口。 DOS系统功能调用的分类: 设备管理、文件管理、目录管理

image-20250510144309474

过程图:

image-20250510144435746

例子:

image-20250510144518497

第七章 高级汇编语言技术
#

1.宏汇编
#

宏:源程序中一段有独立功能的程序代码。 宏指令:用户自定义的指令。在编程时,将多次使用的功能用一条宏指令来代替。

像是模板或者C语言中的宏函数,直接复制粘贴。

注意和子程序调用的区别:

image-20250510144856546

image-20250324144526770

怎么写一个macro,以下的格式,调用的时候和高级语言是类似的:

过程:

image-20250510145309555

image-20250324144758398

这个替换过程的术语:

image-20250324151333203

接着是一些宏函数的特殊规定,看ppt即可……这里就已经有高级语言的味道了……

1.可以没有参数。

2.参数可以是操作数 比如ADD。

3.LOCAL局部的变量,防止冲突。

一个例子:

image-20250510145726531

2.重复汇编
#

image-20250324152602447

image-20250324152832025

例子:

image-20250510150556264

在data segment定义的简化的操作:

image-20250510150704446

IRP

不定的重复,每次用一项来替换REG,天才。

image-20250510150814883

image-20250510150907250

IRPC

用字符串不停地替代哑元,直到结束。

image-20250510151016012

3.条件汇编
#

还是类似于C语言的头文件编译一样的东西……

image-20250324154239528

举个简单例子:

image-20250328142359497

第八章 输入输出程序设计
#

I/O设备的数据传送方式
#

由很多接口上面的寄存器来完成:

image-20250328144029729

I/O端口地址:为了访问接口上的寄存器,系统给这些寄存器分配专门的存取访问地址,这样的地址称为I/O端口地址

  1. 8086/8088CPU系统中,I/O端口地址和存储单元的 地址是各自独立的,分占两个不同的地址空间。
  2. 8086/8088CPU提供的I/O端口地址空间达64KB 可接64K个8位端口(字节),或可接32K个16位端口(字)。
  3. PC及其兼容机实际只使用0~3FFH之间的I/O端口地址。—》(PC只用了10位地址线(A0-A9)进行译码,其 寻址的范围为0H-3FFH,共有1024个I/O地址。)
  4. 存取接口寄存器中的数据是依靠I/O指令完成的。

一些IO指令
#

image-20250328144502876

程序直接控制IO,不停等待,直到可以输入或者输出:
#

查询状态端口的数据。

image-20250328144921114

中断方式
#

如果你对中断感兴趣,可以查看这个网页:https://linux-kernel-labs-zh.xyz/so2/lec4-interrupts.html

中断方式: 当外设准备好时,外设主动向CPU发出中断服务请求,CPU暂时中止现行程序的执行,转入中断服务处理程序完成输入/输出工作,之后返回被中断的程序继续执行。 中断方式特点: CPU和I/O设备能够并行运行。 具有及时处理响应意外事件或异常的能力。

屏蔽中断方式
#

设置IF标志位

image-20250331142110841

硬件中断服务:
#

image-20250331142302930

软件中断是由程序本身导致的:
#

  1. 程序中的中断指令 INT n 操作数n指出中断类型号,0—FFH 如 INT 12H ; 存储器容量测试
  2. CPU的某些运行结果 除法错中断:除数为零/商超出表数范围,中断类型号为0的 内部中断 溢出中断:运算结果溢出,OF=1,INTO指令将引起类型为4 的内部中断
  3. 调试程序(DEBUG)设置的中断 单步中断:标志位TF=1时,中断类型号=1 断点中断:将程序分段,每段设置一个断点(INT 3),中 断类型号=3

中断向量表
#

相当于是一个映射map,设置对应的CS和IP,然后跳转执行对应的中断处理的程序。

image-20250331142741197

X86的内存空间分配(OS课中还会学到):

image-20250331142900026

一个基本处理流程:

image-20250331143424624

中断响应

image-20250510161933736

中断处理

image-20250510162052983

中断返回

CPU自动恢复

image-20250510162206195

和子程序调用的区别:
#

中断与子程序调用处理过程相似,差别主要在于进入和返回时的处理不同。

进入中断服务处理程序时
#

子程序调用:只把CS和IP压入堆栈。 中断:除把CS和IP压入堆栈外,还把标志寄存器的内容压入堆栈,并且关掉了中断和单步运行方式

返回时
#

子程序返回:只把断点地址从堆栈弹出送CS和IP。 中断返回:除恢复断点地址CS和IP外,还要恢复标志寄存器的内容。

时机不同
#

中断:一般随机发生;软中断在程序中预先安排。 子程序调用:程序中预先安排调用。

优先级的处理:
#

image-20250331144514405

80386程序中断
#

看不懂也懒得看了。

BIOS中断和DOS中断
#

以下是ChatGPT的解释

1. 定义
#

BIOS(Basic Input/Output System)
#

  • 固件,存储在主板上的 ROM/EEPROM 芯片中,在计算机开机时运行。
  • 负责执行自检(POST, Power-On Self Test)、初始化硬件、引导操作系统。
  • 提供一组低级别的输入输出服务,如读写磁盘、键盘输入、显示输出、串口通信等。

DOS(Disk Operating System)
#

  • 操作系统,存储在硬盘或软盘中,在 BIOS 引导后加载。
  • 负责管理文件系统、进程、设备驱动、命令解释等功能。
  • 典型的 DOS 版本包括 MS-DOS、PC-DOS、FreeDOS 等。

2. 作用
#

系统 主要作用
BIOS 初始化硬件,执行自检(POST),引导操作系统,提供基础 I/O 接口
DOS 管理磁盘文件系统、提供命令行界面、运行应用程序

3. 联系
#

  1. 启动过程的衔接
    • 计算机上电后,BIOS 首先执行,完成自检并寻找引导设备(软盘、硬盘、光盘等)。
    • BIOS 读取 DOS 的引导扇区(Boot Sector),然后加载 DOS。
    • DOS 依赖 BIOS 来访问低级硬件,如磁盘、键盘、屏幕等。
  2. DOS 依赖 BIOS 进行硬件访问
    • 早期 DOS 不直接控制硬件,而是通过**BIOS 提供的中断(如 INT 13h 读写磁盘,INT 10h 控制显示器)**与硬件交互。
    • 例如,在 DOS 下运行的程序可以通过 INT 21h 调用 DOS 功能,而 INT 10h 直接调用 BIOS 来控制显示器。
  3. BIOS 提供基本的驱动支持
    • DOS 启动时,可以直接使用 BIOS 的设备驱动程序(如磁盘、键盘)。
    • 但 DOS 也可以加载更高级的驱动程序(如 HIMEM.SYS、CD-ROM 驱动等)来替代 BIOS 功能。

4. 区别
#

特性 BIOS DOS
存储位置 ROM/EEPROM 磁盘(硬盘、软盘)
运行时机 计算机启动时 BIOS 加载后
作用 硬件初始化、系统引导 文件管理、命令执行
是否可修改 固定在 ROM(可升级) 软盘/硬盘上,可修改
硬件访问方式 直接控制硬件 通过 BIOS 或驱动访问硬件

5. 总结
#

  • BIOS 是计算机启动的第一步,它初始化硬件,并将操作系统(如 DOS)加载到内存中。
  • DOS 是一个基于磁盘的操作系统,在 BIOS 加载后运行,提供文件管理、命令解释等功能。
  • DOS 依赖 BIOS 进行低级硬件访问,但也可以加载自己的驱动程序绕过 BIOS。
  • 现代操作系统(如 Windows、Linux)已经不再依赖 BIOS,而是直接与硬件交互,但 DOS 仍然常用于嵌入式系统、维修工具等场景。

功能调用 键盘 显示器 打印机

什么是BIOS
#

image-20250331151909444

什么是DOS
#

image-20250331152346907

DOS系统功能调用 INT 21H AH=1 键盘输入并回显 AH=2 显示字符输出 AH=9 显示字符串输出 AH=0AH 键盘输入到缓冲区 AH=4CH 带返回码终止 二者之间的关系:

BIOS是直接操作硬件的

image-20250331152724819

调用方法:

image-20250331152958621

键盘
#

image-20250510162930487

课内测试
#

理论上很多年课内测试的答案都没有改变过,所以你可以拿来参考,摆脱每节课都必须要去的痛苦,但是时间就要你自己来把控……

如果你发现你输入的数据错了(这个没办法,证明人家老师反应过来了),或者是我写的答案有错误,可以在评论区立刻指出来……

号我不知道为什么后面对不上了,自己看看吧……

ch1-1
#

image-20250331154500107

段寄存器:存放了一系列的段的base地址。

ch1-2
#

image-20250505223848467

23451:左边移位直接相加就可以了。

ch1-3
#

image-20250505225954822

寄存器 立即

ch2-1
#

image-20250506202721520

[BX + SI]也就是存储器中取得

**基址变址寻址 **

默认的就是DS段寄存器

ch2-2
#

image-20250506212542301

段间间接

7856 3412 (注意前后顺序)

ch2-3
#

image-20250507190030042

上面的两个操作是独立的:

1232 1236

ch3-1
#

image-20250507223917968

255 255 应该是吧

ch3-2
#

image-20250507230901733

AX DX AX

ch3-3
#

image-20250508215220170

DF 字操作 word—》2 bytes 2

ch4-1
#

image-20250508221259357

ZF = 1 CF = 0

注意标志位即可。

ch4-2
#

image-20250509093211182

B C?(和连接有关系么?斟酌一下)

ch4-3
#

image-20250509100015264

0000 0004 0006

ch5-1
#

image-20250509103255513

26 36

ROL:循环向左移动的指令。

ch5-2
#

image-20250510132306990

从最高位开始:11011100

填写:1 0

ch5-3
#

image-20250510133154509

5678

1234

ch6-1
#

image-20250510140120534

NEAR FAR 很简单的概念

ch6-2
#

image-20250510143132603

寄存器 存储器

ch6-3
#

image-20250510143657001

0403

0203

ch7-1
#

image-20250324153946719

B B

ch7-2
#

image-20250324153324543

A D(我有些疑惑,难道不是节省了时间么(但是确实不节省存储空间),不用进行转移和参数的传递,还是说宏展开的时间把这段时间给浪费了?很奇怪,我牺牲了10分,孩子们)

ch7-3
#

image-20250324153121723

AX BP

ch7-4
#

image-20250328142630184

不带脑子:SHR SHL

ch8-1
#

image-20250328145022658

第一个空就是说把输入状态端口地址的值输入到AL寄存器里面去 82H

第二个空是检查最低位是不是1,那么就使用 01H 检测就可以了

82H 01H

ch8-2
#

image-20250328152109648

外设控制器 协处理器

ch8-3
#

这里也有可能是8-2,看空的个数即可

image-20250331143742327

image-20250331143800362

响应 + 处理 + 返回

ch8-4
#

image-20250331150442783

这是这张PPT之前举的每十秒钟响铃并且打印的例子:

B B(主程序只要调用即可)

ch9-1
#

image-20250331153703982

……

ch9-2
#

image-20250331153859021

*上机实验
#

https://github.com/Pine-G/XJTU-CS2020/tree/main/%E6%B1%87%E7%BC%96%E8%AF%AD%E8%A8%80

这个学长的仓库里有两年的考题以及上机实验的参考代码,合理使用!

我个人认为这个课的代码没有查重,这个得到时候再看吧。

mio
Author
mio
I’m Just A Student…