最近在啃汇编,一大堆的理论知识,感觉挺枯燥的,经常看书看着看着就睡着了😂,现在把一些重要知识点汇总一下

# 字符表示

计算机中的数用二进制表示,数的符号也是用二进制表示,一般数的最高有效位用来表示数的符号,正数为 0,负数为 1,常用的有原码、反码、补码这三种表示,目前计算机基本只采用补码的方式表示

  • 原码

以机器字长 8 位为例: +10D 的原码表示为 0000 1010, -10D 的原码表示为 1000 1010,原码不能直接参与运算,因为高位的符号位会导致运算结果出错

例如 (+1D) - (+1D) 在计算机中会转换成 (+1D) + (-1D) , 用原码表示为 0000 0001 + 1000 0001 = 1000 0010 , 运算结果为 -2D,这个结果明显是错误的

计算机中只有加法器,没有减法器,这是因为减法运算中有一条法则,就是一个数减去另一个数等于加上另一个数的相反数,所以加法器可以同时实现加法和减法的运算,为了简化电路的复杂度,计算机便舍弃了减法器

  • 反码

反码是原码转换补码的一种过渡码,它将原码按位求反,得到的结果即这个数的反码

以机器字长 8 位为例:
+10D 的原码表示为 0000 1010,反码表示为 0000 1010
-10D 的原码表示为 1000 1010,反码表示为 1111 0101

正数的反码、补码和原码一样,负数最高有效位不变,其它位求反

  • 补码

补码是在反码的基础上末位 +1 得到这个数的补码

以机器字长 8 位为例:
+10D 的原码表示为 0000 1010, 补码表示为 0000 1010
-10D 的原码表示为 1000 1010,补码表示为 1111 0110

补码的出现就是为了实现计算机减法运算的问题

例如 (+1D) - (+1D) 在计算机中会转换成 (+1D) + (-1D) , 用补码表示为 0000 0001 + 1111 1111 = 1 0000 0000 , 由于机器字长为 8 位,最高位的 1 会被计算机舍弃掉,结果为 0000 0000

我们可以通过代码来验证 +1D 和 -1D 在计算机内存中表示的数据是不是 0000 00011111 1111

test

# 80x86 寄存器

80x86 CUP 一共有 14 个 16 位寄存器,它们分别是 AX、BX、CX、DX、SP、BP、SI、DI、DS、ES、SS、CS、IP、FLAGS,我觉得其它的寄存器还是比较容易理解的,就是 FLAGS 寄存器有点难记忆

register

其中 AX、BX、CX、DX 为数据寄存器,并且这四个数据寄存器都可以拆分成 2 个独立的 8 位寄存器

16 位高 8 位低 8 位
AXAHAL
BXBHBL
CXCHCL
DXDHDL

SP BP 是指针寄存器,SP 是堆栈指针,BP 是基址指针

SI DI 是变址寄存器,SI 是源地址寄存器,DI 是目的地址寄存器

DS、ES、SS、CS 是段寄存器,DS 是数据段寄存器,ES 是附加段寄存器,SS 是堆栈寄存器,CS 是代码段寄存器

IP 是指令指针寄存器

FLAGS 是标志寄存器,FLAGS 寄存器一共有 9 种标志,其中 1、3、5、12、13、14、15 位并没有使用,FLAGS 寄存器主要用于反映处理器的状态和处理结果的某些特征

1514131211109876543210
OFDFIFTFSFZFAFPFCF
标志名标志为 1标志为 0
OF 溢出 (是 / 否)OV (over flow)NV (not over)
DF 方向 (减少 / 增加)DN (down)UP (up)
IF 中断 (允许 / 关闭)EI (enable interrupt)DI (disable interrupt)
SF 符号 (负 / 正)NG (negative)PL (plus)
ZF 零 (是 / 否)ZR (zero)NZ (not zero)
AF 辅助进位 (是 / 否)AC (auxiliary carry)NA (not auxiliary carry)
PF 奇偶 (偶 / 奇)PE (parity even)PO (parity odd)
CF 进位 (是 / 否)CY (carry)NC (not carry)
  1. OF(overflow flag)

溢出标志,在有符号数值运算过程中,如果操作数超出了机器能表示的范围,OF 标志为 1,否则为 0,溢出标志只对有符号数值运算结果有影响

打开 Debug 测试验证,AL = 49H,BL = 64H,AL + BL = ADH,ADH = 1010 1101B = (173D),在机器字长 8 位的寄存器中,有符号数值取值范围为 -128 ~ 127,其结果造成了溢出,所以这里的 CF 标记为 OV,如果是无符号数值运算,这个结果则是正确的

OV

我刚开始接触 OF 标志时,其实我是有点疑惑的,为什么这里结果是按照有符号数运算,我在网上搜了一下,并没有找到我满意的答案,只好自己通过大量的数值进行测试,最后终于解开了这个疑惑,可以看一下我下面的两段代码的结果,它们的结果都是 ADH,一个溢出了,一个没有溢出,思考一下这是为什么

OF

  1. DF(direction flag)

方向标志,在串处理指令种控制处理信息的方向,当 DF 位为 1 时,每次操作后使 SI DI 值减少,这样串处理便从高地址向低地址的方向处理,当 DF 位为 0 时,每次操作后使 SI DI 值增加,这样串处理便从低地址向高地址的方向处理

  1. IF(interrupt flag)

中断标志,当 IF 位为 1 时,CPU 响应可屏蔽中断请求,否则关闭中断

  1. TF(trap flag)

跟踪标志,用于调试时的单步操作,当 TF 位为 1 时,每条指令执行完后产生中断,由系统控制计算机,当 TF 位为 0 时,CPU 正常工作,不产生中断

  1. SF(sign flag)

符号标志,记录运算结果,与运算结果的最高位相同,运算结果最高位为 1,SF 标志为 1,否则为 0

SF

  1. ZF(zero flag)

零标志,运算结果为 0 时,ZF 位为 1,否则为 0

ZF

  1. AF(auxiliary carry flag)

辅助进位标志,在字节操作时,低半字节 (第 3 个字节) 向高半字节 (第 4 个字节) 进位或者借位,在字操作时,低字节 (第 7 个字节) 向高字节 (第 8 个字节) 进位或者借位,有进位或借位时 AF 位为 1,否则为 0

AF

  1. PF(parity flag)

奇偶标志,用于反馈运算结果中 1 的个数,当结果操作数中低 8 位 1 的个数为偶数时 PF 位为 1,否则为 0

debug 中分别测试一下 1,2,3,0 四个数值 PF 标志的变化

PF

  1. CF(carry flag)

进位标志,记录运算时从最高有效位产生的进位值,例如执行加法指令时最高有效位有进位时 CF 位为 1,否则为 0

CF

Edited on Views times

Give me a cup of [coffee]~( ̄▽ ̄)~*

Bob WeChat Pay

WeChat Pay

Bob PayPal

PayPal

Bob Alipay

Alipay