汇编学习记录1
参考的书籍是: IBM PC汇编语言程序设计(第二版)
有一些收货,记录一下
1 不同进制的编码和补码
2 存储地址编码方式和寄存器
介绍了IBM的20位地址线寻址方式。
机器的一个字大小为16为,但是地址线20位,所以将20为分成两段来组合。
一般我们想到的是最高的4位单独存储,然后再加一个字16位,拼一下即可。
人家把高16位存储,然后加低的4位。
高16位叫段地址,低4位叫做段内偏移。
实际实现是高16位段地址,加低16位段内偏移,这样段与段就混在一起了,低的段内偏移可以影响段地址了。。。
这样设计不乱吗。
段地址分了四个寄存器
CS code segment 代码段
DS data segment 数据段
SS stack segment 堆栈段
ES extra segment 附加段
3 cpu 寄存器
cpu由运算器和控制器两部分组成
1 算术逻辑单元ALU Arithmetic and Logic Unit 2 控制逻辑 3 工作寄存器
其实就是用来计算的电路,控制计算什么走流程的电路和记录当前cpu状态的寄存器。
数据寄存器 AX BX CX DX 每个16位,分高字节低字节
AH AL BH BL CH CL DH DL
指针及变址寄存器
SP BP SI DI
SP 堆栈寄存器 BP 基址寄存器 SI 源变址寄存器 source index DI 目的变址寄存器 destination index
段寄存器
CS DS SS ES
控制寄存器
IP PSW
IP 指令寄存器 指向下一条指令的地址 与cs寄存器连用,一起找到代码
PSW program status word 程序状态寄存器
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
OF | DF | IF | TF | SF | ZF | AF | PF | CF |
包含了条件码标志和控制标志
条件码 OF overflow flag 移除标志 SF sign flag 符号标志,0为正数,1为负数 ZF zero flag 零标志, 是不是0 CF carry flag 进位标志, 最高位是否进位 AF auxillary carry flag 辅助进位标记 记录运算时第3位产生的进位,半字节进位标记 PF parity flag 奇偶标志 字节中的1的个数为偶数时为1
控制标志 DF direction flag 方向标志 在串处理指令中控制信息处理的方向,为1时控制SI DI每次减1,否则加1 IF interrupt flag 中断标志 为1时允许中断 TF trap flag 陷阱标志 为1时就是单步执行。
数据寄存器 状态寄存器 命令寄存器
每个寄存器也可以分配地址
BIOS base input output system DOS disk operating system
4 指令和寻址
指令包含 操作码操作数
寻址
立即寻址 直接写到指令中,比如给寄存器赋值
mov al,5 这里的5就是立即寻址
寄存器寻址
数在寄存器中
直接寻址
数在数据段,需要你用段内偏移和段地址来获取数据的地址,这里的段内偏移也叫EA ,effective Address,用DS寄存器加上你的EA得到真实的数据地址。
例如:
mov AX, [30H]
这里如果DS为3000H,那么实际的数据就在3030H的地方。
寄存器间接寻址
EA在寄存器中。
mov AX, [BX]
也可以指定段寄存器
mov AX, ES:[BX]
寄存器相对寻址
EA是基址或变址寄存器加一个偏移
没看太明白,是用到段寄存器和变址寄存器。
基址变址寻址
基址加变址
mov AX,[BX+DI]
相对基址变址寻址
基址加变址加偏移
mov AX,[2000H+BX+SI]
段内直接寻址
jmp near ptr 16位偏移
jmp short 8位偏移
条件转移指令只能用段内直接寻址8位偏移
段内间接寻址
jmp BX
jmp WORD PTR[BP+TABLE]
段间直接寻址
jmp far ptr
段间间接寻址
jmp DWORD PTR [inters+BX]
机器指令
op d w
op是指令 d 是指定寄存器用于源操作数还是目的操作数 w 是对子操作还是对字节操作
所有双操作数指令必须用一个寄存器,所以上面的d 才有意义
寻址方式的机器表示
mod reg s/m
这个东西有个表格,这里就不复制了
mod
00 表示无位移
01 表示1个字节的偏移
10 表示2个字节的偏移
11 表示2个寄存器
add指令
add dest,src
add mem/reg1, mem/reg2
mem只能生效一个,也就是至少要用一个寄存器
add ax,data
用机器表示就是
0000010w
data 低位
data 高位
w用来控制是用字还是用字节,也就是寄存器是AL,还是AX
add CL,BH
0000010 11001111
前5个0是op,是什么指令
1 是d的意思,是说目的操作数用寄存器
0 是w,是说字节运算。
后面的11 是mod 说是双寄存器,
001 是reg
reg的解读需要看w,w说是字节,那么寄存器就是XL或XH,不是XX
reg | w=1 字 | w=0 字节 |
---|---|---|
000 | AX | AL |
001 | CX | CL |
010 | DX | DL |
011 | BX | BL |
100 | SP | AH |
101 | BP | CH |
110 | SI | DH |
111 | DI | BH |
所以001就是 CL
111 是r/m
r/m 要看mod,还有w,比较复杂
这个表比较复杂就不写了,类似上面的reg
这里的111就是 BH
整体看下来就是
op d w mod reg s/m
00000 1 0 11 001 111
加法指令 目的操作数用寄存器 用字节计算 双寄存器 CL s/m 说是BH
翻译成汇编就是
add CL,BH
ADD DISP[BX][DI], DX
op d w mod reg s/m
00000 0 1 10 010 001 01000101 00100011
翻译就是
加法指令 源操作数用寄存器 字操作 两个字节的偏移 用的寄存器是DX BX+DI+DS 后面分别的是偏移的低8位和高8位
即
ADD [BX][DI], DX
实际计算就是
ADD [DS+BX+DI+偏移], DX
其他指令也是如此,也记不住知道这个格式即可。
又介绍了一下执行指令需要取指令,解析指令,拿操作数,计算,赋值等所消耗的时间,即指令的运行时间,单位为时钟周期。
指令 分为了6种
数据传输指令
算术指令
逻辑指令
串处理指令
控制转移指令
处理机控制指令
数据传输指令包括
mov push pop xchg (交换)
mov dst, src
push AX
pop AX
XCHG opr1, opr2
累加器专用传输指令
IN
OUT
XLAT
IN AL, port 字节
IN AX, port 字
OUT port, AL 字节
OUT port, AX 字
其中port是根据cpu指定的
port端口号是65535 即两个字节 一个字的范围内
和网络的端口很像啊
取一个端口的数值可以像下面这样操作
IN AX, 28H
mov DWORD PTR[], AX
这样就报28H这个端口的数拿出来了。
向某个端口发送数据
OUT 5, AL
就把AL的数据发给了端口5
地址传送指令
LEA load effect address
LDS load DS With Pointer
LES load ES with pointer
标志寄存器传送指令
LAHF
SAHF
PUSHF
POPF
算术指令
ADD
ADC 进位加法
INC 自增
SUB
SBB 借位减法
DEC 自减
NEG 求补
CMP 比较
MUL 无符号乘
IMUL 有符号乘
DIV
IDIV
CBW 字节转字
CWD 字转字节
十进制表示只用4个bit就行,而一个字节是8为,计算机实际计算用的也是这8位,想表示成人看的结果,需要将结果表示成10进制,即4位,4位的bit组成的10进制结果。
DAA decimal adjust