Pil0tXia 的书房 Pil0tXia 的书房
首页
  • 第一章 操作系统引论
  • 第二章 进程的描述与控制
  • 第三章 处理机调度与死锁
  • 第四章 存储器管理
  • 第五章 虚拟存储器
  • 期末考试备考
汇编语言课程笔记
GitHub (opens new window)
首页
  • 第一章 操作系统引论
  • 第二章 进程的描述与控制
  • 第三章 处理机调度与死锁
  • 第四章 存储器管理
  • 第五章 虚拟存储器
  • 期末考试备考
汇编语言课程笔记
GitHub (opens new window)
  • 汇编语言课程笔记

    • 课堂速记
      • 引入 进制转换
        • 十六转十进制
        • 十六转二进制
        • 十进制转十六
        • 二进制转十六
        • 十进制转二进制
        • 二进制转十进制
        • 巧算法
      • 第二章 寄存器
        • 8086 访问地址
        • CS:IP
      • 第三章 寄存器(内存访问)
        • 内存中字的存储
        • 例1
        • 例2
        • 堆栈
        • 先进后出
        • SS:SP
      • 第四章
        • 源程序中的“程序”
        • 汇编程序&伪指令
        • 编译&连接
        • 谁将可执行文件中的程序装载进入内存并使它运行?
        • EXE文件中的程序的加载过程 DS
        • 程序执行过程的跟踪
      • 第六章 包含多个段的程序
        • 在代码段中使用数据
        • 在代码段中使用栈
        • 将数据、代码、栈放入不同的段
      • 第七章 更灵活的定位内存地址的方法
        • ASCII码
        • [bx+idata] 寄存器相对寻址
        • SI和DI 基址变址寻址
        • 相对基址变址寻址([bx+si+idata]和[bx+di+idata])
      • 第八章 数据处理的两个基本问题
        • bx,si,di,bp
        • 寻址方式
        • 指令要处理的数据有多长?
        • div指令 书P169
      • 第九章 转移指令的原理
        • offset
        • jmp
      • 第十一章
        • PF标志(Parity)
        • SF标志(Sign)
        • ZF标志(Zero)
        • CF标志(Carry)
        • OF标志(Overflow)
        • adc指令
        • sbb指令
        • cmp指令
        • je指令等
        • DF标志和串传送指令
      • 第十二章 内中断
      • 第十三章 int指令
        • 13.5 BIOS和DOS中断例程的安装过程
      • 第十四章
        • shl和shr指令
      • 期末考试复习
  • 《汇编语言》第三版阅读笔记

    • 第一章 基础知识
    • 第二章 寄存器
    • 第三章 寄存器(内存访问)
    • 第四章 第一个程序
    • 第五章 [BX]和loop指令
    • 第六章 包含多个段的程序
    • 第七章 更灵活的定位内存地址的方法
    • 第八章 数据处理的两个基本问题
    • 第九章 转移指令的原理
    • 第十章 CALL和RET指令
    • 第十一章 标志寄存器
    • 第十二章 内中断
  • 汇编语言
  • 汇编语言课程笔记
Pil0tXia
2023-01-05
目录
引入 进制转换
十六转十进制
十六转二进制
十进制转十六
二进制转十六
十进制转二进制
二进制转十进制
巧算法
第二章 寄存器
8086 访问地址
CS:IP
第三章 寄存器(内存访问)
内存中字的存储
例1
例2
堆栈
先进后出
SS:SP
第四章
源程序中的“程序”
汇编程序&伪指令
编译&连接
谁将可执行文件中的程序装载进入内存并使它运行?
EXE文件中的程序的加载过程 DS
程序执行过程的跟踪
第六章 包含多个段的程序
在代码段中使用数据
在代码段中使用栈
将数据、代码、栈放入不同的段
第七章 更灵活的定位内存地址的方法
ASCII码
[bx+idata] 寄存器相对寻址
SI和DI 基址变址寻址
相对基址变址寻址([bx+si+idata]和[bx+di+idata])
第八章 数据处理的两个基本问题
bx,si,di,bp
寻址方式
指令要处理的数据有多长?
div指令 书P169
第九章 转移指令的原理
offset
jmp
第十一章
PF标志(Parity)
SF标志(Sign)
ZF标志(Zero)
CF标志(Carry)
OF标志(Overflow)
adc指令
sbb指令
cmp指令
je指令等
DF标志和串传送指令
第十二章 内中断
第十三章 int指令
13.5 BIOS和DOS中断例程的安装过程
第十四章
shl和shr指令
期末考试复习

课堂速记

# 课堂速记

本笔记使用教材《汇编语言(第三版)》,王爽,清华大学出版社

# 引入 进制转换

# 十六转十进制

就用乘法,每一位乘以 16^0, 16^1, 16^2 ... 然后加在一起。

举个例子,ff bf 是几?答:65471

# 十六转二进制

更简单了,只需把每一位,变成二进制的四位数,然后拼在一起。

看个例子就懂了,ff bf 是二进制的几?答:1111 1111 1011 1111

# 十进制转十六

稍微复杂些,用短除法。每次除以 16,把余数从下到上拼起来,就得到了 16 进制的数。

来一起试试,65471 是十六进制的几?答:ff bf

# 二进制转十六

又容易了,只需切成 4 个 4 个的小段,把每段对应的字母 / 数字拼在一起,就可以了。

比如这个例子,11 1111 1011 1111 是几?答:3f bf

# 十进制转二进制

除二取余,倒序排列,高位补零。

# 二进制转十进制

同十六转十进制,但 16 改成 2

# 巧算法

如何快速把 2^n 的十进制数,转换为二进制?

只需把 n 除以 4,得到 j 余 i。把 i 变成 2^i 做为第一位,其余的就是,j 是几就跟几个零。

# 第二章 寄存器

# 8086 访问地址

image-20220913160043333

image-20220913160006739

image-20220913160226911

image-20220913160311958

一个段的最大大小为 2^16=65536=64K,此为偏移地址的最大表示大小 FFFFH。

image-20220913160354815

# CS:IP

代码段的段地址存放在 CS 中,指令指针寄存器 IP 指示代码段中指令的偏移地址,处理器利用 CS:IP 取得下一条要执行的指令。

image-20220913160541141

# 第三章 寄存器(内存访问)

# 内存中字的存储

image-20220913155716253

(1) 20H (2) 4E20H

字节型数据<字型数据。一个字型数据 (如 1234H) 存放在内存中,由 2 个连续的地址的内存单元组成。高地址内存单元存放字型数据的高位字节,低地址内存单元存放字型数据的低位字节。

image-20220913160921444

image-20220913182153695

image-20220913182321717

mov 的大小就是 al 的大小

image-20220913175140878

image-20220913182520984

此处 “一般的寄存器” 就是上例中的 bx

# 例 1

image-20220920084151074

# 例 2

image-20220920090126282

1200+7C0A+4532+A963(舍弃溢出)

# 堆栈

8086CPU 入栈出栈都以字为单位,不能 push/pop 一个 al

# 先进后出

image-20220920090712907

# SS:SP

image-20220920090806265

image-20220920091135542

入栈出栈时 SP 会先进行 - 2/+2 的操作,push 时 SP 向上(低位)移动 - 2。然后将数据送入 SS:SP 指向的内存单元处。

image-20220920094349099

image-20220920094416090

image-20220920094504975

image-20220920094531191

image-20220920094635326

image-20220920095356999

# 第四章

# 源程序中的 “程序”

汇编源程序:

  • 伪指令(编译器处理)
  • 汇编指令(编译为机器码)

程序:源程序中最终由计算机执行、处理的指令或数据。

# 汇编程序 & 伪指令

codesg:标号,放在 segment 的前面,作为一个段的名称,这个段的名称最终将被编译、连接程序处理为一个段的段地址。

image-20220927170327619

image-20220927170240588

# 编译 & 连接

当源程序很大时,可以将它分为多个源程序文件来编译,每个源程序编译成为目标文件后,再用连接程序将它们连接到一起,生成一个可执行文件;

程序中调用了某个库文件中的子程序,需要将这个库文件和该程序生成的目标文件连接到一起,生成一个可执行文件;

一个源程序编译后,得到了存有机器码的目标文件,目标文件中的有些内容还不能直接用来生成可执行文件,连接程序将这些内容处理为最终的可执行信息。

所以,在只有一个源程序文件,而又不需要调用某个库中的子程序的情况下,也必须用连接程序对目标文件进行处理,生成可执行文件。

# 谁将可执行文件中的程序装载进入内存并使它运行?

在 DOS 中,可执行文件中的程序 P1 若要运行,必须有一个正在运行的程序 P2 将 P1 从可执行文件中加载入内存,将 CPU 的控制权交给它,P1 才能得以运行;当 P1 运行完毕后,应该将 CPU 的控制权交还给使它得以运行的程序 P2。

(1)我们在 DOS 中直接执行 1.exe 时,是正在运行的 command 将 1.exe 中的程序加载入内存。

(2)command 设置 CPU 的 CS:IP 指向程序的第一条指令(即程序的入口),从而使程序得以运行。

(3)程序运行结束后,返回到 command 中,CPU 继续运行 command

image-20220927201137970

# EXE 文件中的程序的加载过程 DS

image-20220927203832279

程序加载后,ds 中存放着程序所在内存区的段地址,这个内存区的偏移地址为 0,则程序所在的内存区的地址为:ds:0;

这个内存区的前 256 个字节中存放的是 PSP,dos 用来和程序进行通信。

所以,我们从 ds 中可以得到 PSP 的段地址 SA,PSP 的偏移地址为 0,则物理地址为 SAX16+0。

因为 PSP 占 256(100H)字节,所以程序的物理地址是:

SA×16+0+256= SA×16+16×16= (SA+16)×16+0

可用段地址和偏移地址表示为:SA+10:0

# 程序执行过程的跟踪

用 R 命令查看各个寄存器的设置情况

image-20220927211120745

用 U 命令查看其他指令

image-20220927211023177

使用 P 命令执行 int 21

使用 Q 命令退出 Debug

# 第六章 包含多个段的程序

# 在代码段中使用数据

IMG_20221004_082246

程序解读见书 P124。 mov ax,4c00h 代表终止。

程序 6.2

end start 除了通知编译器程序结束外,还可以通知编译器程序的入口在什么地方。

# 在代码段中使用栈

程序 6.3

30h 是 48 字节,正好对应 dw 分配的 16 个字型数据,用于栈的空间。

# 将数据、代码、栈放入不同的段

程序 6.4

cs 是自动装载的,不用在代码段中指定 cs 的指向。

  • 为什么 mov bx,0 可以将 ds:bx 指向 data 段中的第一个单元?

    因为 0 被认为是 ds,[0]

  • 为什么 mov cx,5 表示循环 5 次?

    cs 用来控制循环次数,每次执行 loop 指令时,都会检查 cs 的值是否为 0

# 第七章 更灵活的定位内存地址的方法

# ASCII 码

程序 7.1

inc 加 1,而不是加 2,因为一个 ASCII 码占一个字节

# [bx+idata] 寄存器相对寻址

[bx+idata] 表示一个内存单元,它的偏移地址为 (bx)+idata(bx 中的数值加上 idata)

mov ax,[bx+200]

数学化描述:(ax)=((ds)*16+(bx)+200)

# SI 和 DI 基址变址寻址

类似于 bx,但是不能分成两个 8 位寄存器

段寄存器、两个内存单元之间、两个段之间都不能直接 mov,需要用寄存器中转

SI 元变址寄存器

DI 目的变址寄存器

# 相对基址变址寻址([bx+si+idata] 和 [bx+di+idata])

问题 7.1、7.3、7.4、7.5 的分析很实用

# 第八章 数据处理的两个基本问题

用 reg 表示一个寄存器,sreg 表示段寄存器

# bx,si,di,bp

bp 用于在堆栈段上寻址,bs 默认用于数据段寻址。都是基址 (base)

“两个 i 不相见,两个 b 不相见”

错误指令:

mov ax,[bx+bp]

mov ax,[si+di]

只要在 [...] 中使用寄存器 bp,且指令中没有显性地给出段地址,段地址就默认在 ss 中。

# 寻址方式

P164 表 8.2

# 指令要处理的数据有多长?

word ptr 和 byte ptr 来显式的指定内存单元的长度

P166: mov word ptr [1000H],1 -> 0100FF

# div 指令 书 P169

div byte ptr ds:[0]

(al) = (ax) / ((ds) * 16 + 0) 的商

(ah) = (ax) / ((ds) * 16 + 0) 的余数

div word ptr es:[0]

(ax) = [(dx) * 10000H + (ax)] / ((es) * 16 + 0) 的商

(dx) = [(dx) * 10000H + (ax)] / ((es) * 16 + 0) 的余数

低商高余

例题

mov ax,data

mov ds,ax

mov ax,ds[0]

mov dx,ds[2]

div word ptr ds:[4]

# 第九章 转移指令的原理

# offset

P175、176

问题 9.1 为什么要加 cs: ?

不加冒号复制的是默认 ds 段

# jmp

讲得太快

# 第十一章

# PF 标志(Parity)

表示奇偶性,1 的个数为奇数时 PF=0,为偶数个时 PF 为 1

# SF 标志(Sign)

结果为负那么 SF=1,结果非负数则 SF=0;

# ZF 标志(Zero)

结果为 0 那么 ZF=1, 结果不为 0 则 ZF=0;

# CF 标志(Carry)

mov al,97H

sub al,98H

执行后:(al)=FFH, CF=1, CF 记录了向更高位的借位值

10010111

10011000

(-1)11111111

FFH

# OF 标志(Overflow)

mov al,98
add al,99
1
2
1
2

执行后 CF=0, OF=1

对于无符号数运算,没有进位,CF=0;对于有符号数运算,发生了溢出(数值位向符号位进了一位,虽然污染了符号位,但此时数还是八位。如果进到第九位,则产生了进位),OF=1

# adc 指令

mov ax,1
add ax,ax
adc ax,3
1
2
3
1
2
3

adc 利用了 CF,执行时相当于计算 (ax)+3+CF=2+3+0=5

计算 1EF000H+201000H,结果放在 ax(高 16 位)和 bx(低 16 位)中

mov ax,001EH
mov bx,F000H
add bx,1000H
adc ax,0020H
1
2
3
4
1
2
3
4

# sbb 指令

adc 的减法版

# cmp 指令

不保存结果的减法比较,仅仅根据结果设置标志位

IMG_20221101_091647

cmp 比较大小不能仅靠 SF,因为可能溢出,还需要借助 OF

  • SF=1, OF=0,说明没有溢出,逻辑上结果正负 = 实际上结果正负,即 ah<bh

  • SF=1, OF=1,溢出会污染符号位,正负性颠倒,即 ah>bh

  • SF=0, OF=1,跟刚才逻辑一样,ah<bh

  • SF=0, OF=0,ah>bh;若 ZF=0,则 ah=bh

任意一个为 1,另一个为 0 时,前者<后者

# je 指令等

IMG_20221101_093204

有符号位的是 jl(小于)、jg(大于)

# DF 标志和串传送指令

df=0 每次操作后 si、di 递增

df=1 每次操作后 si、di 递减

movsb 将 ds:si 指向的内存单元的一个字节送入 es:di 中,然后根据 df 位的值,将 si 和 di 递增或递减

movsw

rep

# 第十二章 内中断

中断向量表 四个单元

do0

# 第十三章 int 指令

int n,n 是中断类型码,功能是引发中断,相当于引发一个 n 号中断的中断过程,执行过程:

标志寄存器入栈,IF=0,TF=0;CS、IP 入栈;(IP)=(n*4), (CS)=(n*4+2)

# 13.5 BIOS 和 DOS 中断例程的安装过程

编程时可以用 int 指令调用 BIOS 和 DOS 提供的中断例程

//不重要
mov ah,9 //调用设置光标的子程序
mov al,'a'
mov bh,7 //颜色设置
1
2
3
4
1
2
3
4

# 第十四章

# shl 和 shr 指令

逻辑移位指令。将一个寄存器或内存单元中的数据向左移位,最后移出的一位写入 CF 中,最低为用 0 来补充。移动位数大于 1 时,必须把移动位数放在 cl 中。

shl 左移,shr 右移。会影响到符号位。(算术右移不会影响符号位)

# 期末考试复习

选择,可能有判断题

写一些指令,进行纠正

2 道编程题

宏不作要求

一直到系统调用,比较重要

https://github.com/sanmianti/AssemblyLanguageTest/blob/master/%E3%80%8A%E6%B1%87%E7%BC%96%E8%AF%AD%E8%A8%80%E3%80%8B%E7%AC%AC%E4%B8%89%E7%89%88%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0.md

上次更新: 2023/01/06, 19:28:46

第一章 基础知识→

Copyright © 2022-2025 Pil0tXia | CC BY-NC-SA 4.0 Licensed | 苏ICP备2023001491号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式