pushf-popf

Tutorial: 汇编基础 Category: C语言 Published: 2026-04-07 13:58:26 Views: 20 Likes: 0 Comments: 0
1. 检测点 11.4

下面的程序执行后:(ax)= ?

assume cs:code, ss:stack, ds:data

; pushf 和 popf 是对标志寄存器的操作指令, 本质上还是对数据的操作, 
; 标志寄存器是16位, 与通用寄存器(ax,bx……)不一样的是它是按"位"起作用的, 
; 即每一"位"都有它自己的含义, 而通用寄存器整体表示一个含义

; 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

data segment
           db 16 dup (0)
data ends

stack segment stack
            db 128 dup (0)
stack ends

code segment
      start:
            mov   ax,0
            push  ax
            popf                    ; 弹出的即push进的AX的值, 即将AX的值给了标志寄存器, 此时标志寄存器的16位都是零
            mov   ax,0fff0h
            add   ax,0010h
      ; add完后结果是10000H, 显然无符号数计算有进位, 所以CF=1,无符号数对OF不起作用, 所以OF=0, 
      ; 值未变, SF=0, PF=1, ZF=1, DF=0, 
      ; 所以该指令执行完毕后, 标志寄存器为:0000 0000 0100 0101

      ; AX=FFF0  BX=0000  CX=00A7  DX=0000  SP=0080  BP=0000  SI=0000  DI=0000
      ; DS=0E14  ES=0E14  SS=0E25  CS=0E2D  IP=0008   NV UP DI PL NZ NA PO NC
      ; 0E2D:0008 83C010        ADD     AX,+10
      ; -t ; ZR, PE, CY = 1
      ; AX=0000  BX=0000  CX=00A7  DX=0000  SP=0080  BP=0000  SI=0000  DI=0000
      ; DS=0E14  ES=0E14  SS=0E25  CS=0E2D  IP=000B   NV UP DI PL ZR NA PE CY

      ; .                   OF   DF   IF  TF  SF  ZF      AF      PF      CF
      ; 15   14   13   12   11   10   9   8   7   6   5   4   3   2   1   0
      ; 0    0    0    0    0    0    0   0   0   1   0   0   0   1   0   1
            pushf                   ; 将psw= 0000 0000 0100 0101 = 47h值压入栈
      ; -t
      ; AX=0000  BX=0000  CX=00A7  DX=0000  SP=007E  BP=0000  SI=0000  DI=0000
      ; DS=0E14  ES=0E14  SS=0E25  CS=0E2D  IP=000C   NV UP DI PL ZR NA PE CY
      ; 0E2D:000C 58            POP     AX
      ; -d ss:7e
      ; 0E25:0070                                            47 00                 G.
      ; 0E25:0080  B8 00 00 50 9D B8 F0 FF-83 C0 10 9C 58 24 C5 80   ...P........X$..
            pop   ax                ; 将之前压入的值赋给al=47h(01000111)ah=0h(00000000)
      ; -t
      ; AX=0047  BX=0000  CX=00A7  DX=0000  SP=0080  BP=0000  SI=0000  DI=0000
      ; DS=0E14  ES=0E14  SS=0E25  CS=0E2D  IP=000D   NV UP DI PL ZR NA PE CY
      ; 0E2D:000D 24C5          AND     AL,C5
            and   al,11000101b
      ; 0100 0101
      ; 1100 0101  异与后al=45h(01000101),ah不变
            and   ah,00001000b
      ; 0000 0000
      ; 0000 1000 异与后ah=0h (00000000), al不变
            mov   ax,4c00h
            int   21h

      ; AX=0047  BX=0000  CX=00A7  DX=0000  SP=0080  BP=0000  SI=0000  DI=0000
      ; DS=0E14  ES=0E14  SS=0E25  CS=0E2D  IP=000D   NV UP DI PL ZR NA PE CY
      ; 0E2D:000D 24C5          AND     AL,C5
      ; -t
      ; AX=0045  BX=0000  CX=00A7  DX=0000  SP=0080  BP=0000  SI=0000  DI=0000
      ; DS=0E14  ES=0E14  SS=0E25  CS=0E2D  IP=000F   NV UP DI PL NZ NA PO NC
      ; 0E2D:000F 80E408        AND     AH,08
      ; -t
      ; AX=0045  BX=0000  CX=00A7  DX=0000  SP=0080  BP=0000  SI=0000  DI=0000
      ; DS=0E14  ES=0E14  SS=0E25  CS=0E2D  IP=0012   NV UP DI PL ZR NA PE NC
      ; 0E2D:0012 B8004C        MOV     AX,4C00

code ends
end start
Prev: 逻辑指令 Next: 内中断