考察知识点:
- AND指令的理解
- 标志寄存器所在16bit的构成
- 无符号运算、有符号运算,分别影响哪些标志寄存器
- 溢出,是否有进位,都是相对于要容纳结果的寄存器而言的,同1个数,用AL,和AX去容纳,前者溢出,后者可能不溢出,取决于寄存器的容纳范围
分析:
- 不论是有符号运算,还是无符号运算,得到的结果都是一样的(只是它们代表实际意义不同,无符号就是值本身,而有符号还要转为原码)
- 不用担心是不是要运算两遍(分成有符号的,和无符号的,会各有一套标志寄存器的值结果)。不用!
- 因为CF只受无符号运算影响;SF,OF只受有符号运算影响
- 所谓进位,或溢出,都是指相对于要容纳结果的寄存器而言,能不能完整容纳。用AX容纳时,就要看是否在[-32768,32767]范围内,用al或ah容纳时,就要看是否在[-128,127]范围内
- PF受运算结果影响(与逻辑结果无关),而两种运算的结果都是一样的,所以PF不会因有无符号运算而不同
- ZF也是同样的道理,受同一个结果影响
- DF受制于cld,std这种人工指令的影响。如果没有人工干预,它会一直保持不变
- 因为CF只受无符号运算影响;SF,OF只受有符号运算影响
以下是我自己的理解:
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 | |||||||
0 | 0 | 1 | 1 | 1 | |||||||||||
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||||
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 |
mov ax,0
push ax
popf;将ax的所有位(全是0)给到了标志寄存器,所以此时所有flag全部为0,8086CPU中存储flag的16个bit中的未启用的bit位也是0
mov ax,0fff0h;无符号为fff0h,有符号为-16
add ax,0010h;无符号为10h,有符号为-240
;截止此时,此步add的运算结果为10000h,用AX只能表示不完整的0000h,ZF=1
;无符号运算有进位,故CF=1
;有符号运算结果为-256,因为是用AX来容纳,所以它在[-32768,32767]范围内,无溢出,故OF=0
;PF=1 (它只看AX中的结果,而不是完整的10000h)
pushf;入栈的是45H
pop ax;出栈的也是45H,0000 0000 0100 0101(我这时曾犯过错误,误PF写成0,导致结果成为41H)
and al,11000101B;al为0100 0001,AND之后变为 0100 0101
and ah,00001000B;ah为0000 0000,AND之后还是 0000 0000
;最终AX仍是45H