or
0 or 0 = 0
0 or 1 = 1
1 or 0 = 1
1 or 1 = 1
在处理器内部,or指令的目的操作数可以是8位或16位的通用寄存器,或包含8/16位实际操作数的内存单元,源操作数可以是与目的操作数数据宽度相同的通用寄存器,内存单元或立即数。比如:
or al, cl
or ax, dx
or [label_a], bx
or byte [bx], 0x55
or指令不允许目的操作数和源操作数都是内存单元的情况。
or指令对标志寄存器的影响是,OF和CF位被清零,SF,ZF,PF位的状态依计算结果而定,AF位的状态未定义。
and
0 and 0 = 0
0 and 1 = 0
1 and 0 = 0
1 and 1 = 1
相应地,处理器设计了and指令。在16位处理器上,and指令的两个操作数都应当是字节或者字。其中,目的操作数可以是通用寄存器和内存单元;源操作数可以是通用寄存器,内存单元,或者立即数。但不允许两个操作数同时为内存单元,且它们在数据宽度上应当一致。比如:
and al, 0x55
and ch, cl
and ax, dx
and [label_a], ah
and word [bx], 0xf0f0
and dx, [bx + si]
当这些指令执行时,两个操作数对应的各个比特位分别进行逻辑"与",结果保存在目的操作数中。and指令执行后,OF和CF位被清零,SF,ZF,PF位的状态依计算结果而定,AF位的状态未定义。
在16位处理器上,push指令的操作数可以是16位的寄存器或内存单元。例如:
push ax
push word [label_a]
8086处理器只能压入一个字,但其后的32位和64位处理器允许压入字,双字,四字。就8086处理器来说,压入栈的内容必须是字。下面指令非法
push al
push byte [label_a]
处理器在执行push指令时,首先将栈指针寄存器SP的内容减去操作数的字长【以字节为单位,16位处理器上为2】,然后,把要压入栈的数据存放到逻辑地址SS:SP所指向的内存位置。
例子中,当push第一次执行时,SP的内容减去2,即0x0000 - 0x0002 = 0xFFFE,借位被忽略。于是,被压入栈的数据在内存中的位置实际是0x0000:0xFFFE。push指令的操作数是字,且Intel处理器是使用低端字节序的,故低字节在低地址部分,高字节在高地址部分,正好占据栈段最高两个字节位置。
代码段在处理器上执行时,由低地址向高地址端推进。压栈,是从高地址端向低地址端推进的。push指令不影响任何标志位。
1.5.3.出栈并显示各个数位
pop dx指定的功能是将逻辑地址SS:SP处的一个字弹出到寄存器DX中,然后将SP的内容加上操作数的字长【2】。
和push指令一样,pop指令的操作数可以是16位的寄存器或内存单元。例如:
pop ax
pop word [label_a]
pop指令执行时,处理器将栈段寄存器SS的内容左移4位,再加上栈指针寄存器SP的内容,形成20位的物理地址访问内存,取得所需数据。然后,将SP的内容加操作数的字长,以指向下一个栈位置。pop指令不影响任何标志位。