(2011.11.02)汇编_王爽_第11章_学习小结
本章内容:
1. 介绍标志寄存器flag中的标志,以及各标志相应的指令,如何运用这些标志。
2. pushf和popf,可以直接访问标志寄存器,pushf将flag压栈,popf将flag弹出数据。
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
8086CPU的flag寄存器结构如下所示:
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
OF DF IF TF SF ZF AF PF CF
溢 方 符 零 奇 进
标志寄存器在Debug中的表示,对照表:
AX = 0000 BX = 0000 CX = 0000 DX = 0000 SP = FFEE BP = 0000 SI = 0000 DI = 0000
DS = **** ES = **** SS = **** IP = 0100 NV UP EI PL NZ NA PO NC
标志 值为1标记 值为0的标记
of OV NV
sf NG PL
zf ZR NZ
pf PE PO
cf CY NC
df DN UP
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; 程序名称:1106_adc指令_两个128位数据进行相加.asm
; 程序说明:编写一个子程序,对两个128位数据进行相加
; 参数: ds:si 指向存储第一个数的内存空间,ds:di指向第二个数的内存空间
; 因数据为128位,所以需要8个字单元,也可理解为需要8次ax
; 由低地址单元到高地址单元依次存放128位数据由低到高的各个字。
; 运算结果存储在第一个数的存储单元中。
; adc指令介绍:
; adc是带进位加法的指令,它利用了CF位上记录的进位值
; 附:sbb指令是带借位减法指令
; 指令格式:adc操作对象1, 操作对象2
; 指令功能: 操作对象1 = 操作对象1 + 操作对象2 + CF
; 指令实例: adc ax, bx
; 实现功能: (ax) = (ax) + (bx) + CF
; 指令实例: sbb ax, bx
; 实现功能: (ax) = (ax) - (bx) - CF
; 主要思想:加法可以分两步来进行:
; 1. 低位相加 2. 高位相加再加上低位相加产生的进位值
add 128:
push ax
push cx
push si
push di
sub ax, ax ; 将CF设零
mov cx, 8
s:
mov ax, [si] ; 第一位数放入ax中
adc ax, [di] ; 将已进入ax 的第一位数与第二位数相加
mov [si], ax ; 相加结果已放入ax, 再将ax移回第一位数的内存单元中保存
inc si ; 因为它为字单元,因为加2
inc si ; 不使用add,为了防止影响CF,下次执行adc 时可能会出错。
inc di
inc di
pop di
pop si
pop cx
pop ax
ret ; 程序返回
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; 程序名称:1108_cmp指令_统计某一范围内的数据个数.asm
; 程序功能:统计F000:0处32个字节中,大小在(32, 128)的数据的个数。
assume cs:code
code segment
start:
mov ax, 0f000h
mov ds, ax
mov bx, 0
mov dx, 0
mov cx, 32
s:
mov al, [bx]
cmp al, 32
jb s0 ; 低于32则跳出计数
cmp al, 128
ja s0 ; 高于128则跳出计数
inc dx
s0:
inc bx
loop s
mov ax, 4c00h
int 21h
code ends
end start
; cmp 是比较指令,cmp的功能相当于减法指令,只是不保存结果。
; cmp指令格式: cmp 操作对象1, 操作对象2
; cmp功能: 操作数1 - 操作数2, 根据计算结果对寄存器进行设置。
; 影响flag的相关各位,指令执行后:zf, pf, sf, cf, of会有所改变。
; 如果溢出导致了实际结果为负,那么逻辑上真正的结果必然为正。
; 如果因为溢出导致了实际结果为正,那么逻辑上真正的结果必然为负。
; 无符号数的比较结果进行转移的条件转移指令
; 指令 含义 检测相关标志位
; je 等于则转移 zf = 1
; jne 不等于则转移 zf = 0
; jb 低于则转移 cf = 1
; jnb 不低于则转移 cf = 0
; ja 高于则转移 cf = 0 且 zf = 0
; jna 不高于则转移 cf = 1 或 zf = 1
; e: 表示 equal || ne :表示 not equal
; b: 表示 below || nb :表示 not below
; a: 表示 above || na :表示 not above
; 不管转移指令前面是什么指令,只要CPU执行je指令时,zf = 1, 那么就会发生转移。
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; 程序名称:1110_DF标志和串传送指令_复制字符串.asm
; 程序功能:编程,用串传送指令,将data段中的第一个字符串复制到它后面的空间中。
assume cs:code, ds:data
data segment
db 'Welcome to masm!'
db 16 dup (0)
data ends
code segment
mov ax, data
mov ds, ax
mov si, 0 ; ds:si指向data:0
mov es, ax ;
mov di, 16 ; es:di指向data:0010
mov cx, 16 ; (cx) = 16, rep 循环16次
cld ; 设置df=0, 正向传送
rep movsb
mov ax, 4c00h
int 21h
code ends
end
; cld 指令:令 DF = 0,每次操作后si, di递增
; std 指令:令 DF = 1,每次操作后si, di递减
; 指令:movsb / mov sw
; 功能:
; 第一步: mov es:[di], byte/word ptr ds:[si] ;8086并不支持这样的指令,这里只是个描述
; 第二步: df = 0时, inc si, inc di
; df = 1时, dec si, dec di
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; 程序名称:实验11_将字符串的小写字母转换为大写字母.asm
assume cs:codesg
datasg segment
db "Beginner's All-purpose Symbolic Instruction Code.", 0
datasg ends
codesg segment
begin:
mov ax, datasg
mov ds, ax
mov si, 0
call letterc
mov ax, 4c00h
int 21h
; 名称:letterc
; 功能:将以0结尾的字符串中的小写字母转变成大写字母
; 参数:ds:si指向字符串的首地址
letterc:
c0:
mov cl, ds:[si]
mov ch, 0
jcxz ok
c1:
mov al, 'a'
mov ah, ds:[si]
cmp ah, al
jb loops ; ah小于al时,直接跳出,设定'a'~'z'的范围
c2:
mov al, 'z'
cmp ah, al
ja loops ; ab大于al时,直接跳出,设定'a'~'z'的范围
change:
and ah,1101111b ; 将字符转换为大写
mov ds:[si], ah
loops:
inc si
jmp c0
ok:
ret
codesg ends
end begin