1、6.1.2 进栈与出栈指令栈操作指令以它特有的方式存取数据,属于数据传递类指令,但又与MOV等指令有很大的区别。,6.1.2.1 PUSH指令【指令格式】PUSH d 【功能】先把SP的值减去2,然后把操作数d指明的字型数据放入以SS为段地址、SP为偏移地址所对应的内存单元中。【说明】 (1)这是单操作数指令,操作数d可以是包括段寄存器在内的任何字型寄存器,或者内存型寻址方式,但不能是立即寻址,当使用内存型寻址方式时可以使用段跨越。 (2)PUSH指令的功能包括移动栈顶和存入数据两部分,两部分连续完成,密不可分。,(3)操作数d进栈是以减2以后的SP的值作为偏移地址,但程序中不允许出现SP的写
2、法。不要与基地址寄存器或变址寄存器用作偏地址时的写法相混淆,也就是说,把PUSH指令理解成下面两条指令的组合是不正确的: SUB SP, 2MOV SP, d因为指令“MOV SP, d”存在语法错误。 (4)PUSH指令会导致栈顶指针的移动,如果用PUSH指令把很多数据进栈,使SP不断减2,就有可能超出栈的有效范围。在一些高级语言中这种现象会导致堆栈溢出错误,但8088对此并不做任何检测和警告。因此要求编程人员自己注意控制堆栈的大小,估计可能进栈的数据量,以免由于栈溢出导致一些不可预测的后果。,6.1.2.2 POP指令【指令格式】POP d 【功能】从SS为段地址、SP为偏移地址对应的内存
3、中取出一个字型数据,送到操作数d指定的位置,然后把SP的值加2。对操作数d的寻址方式要求与PUSH指令相同。 堆栈通常用于临时保存数据。一般做法是先用PUSH指令把需要保存的数据入栈,然后完成一定的指令序列,再用POP指令把原先保存的数据出栈。用堆栈保存数据的特点是不用定义变量,不必关心被保存的数据到底在栈的什么位置,只要保证出栈和进栈的对应关系即可。当CPU中的寄存器不够使用时经常用堆栈临时保存数据。,栈顶所指位置以上的部分是堆栈的空闲区,以下部分是已入栈的数据存放区(见图6.1),例6.1用来说明PUSH指令和POP指令对堆栈的影响。【例6.1】设AX4F8AH,BX307CH,SP100
4、0H,分别逐条执行下列指令,用内存图的形式画出堆栈的变化情况,并分析程序段执行完后AX和BX寄存器的值。PUSH AXPUSH BXPOP AXPOP BX,【解】堆栈变化见图6.2,程序段执行完后AX307CH,BX4F8AH。,XX 0FFC,XX 0FFD,XX 0FFE,XX 0FFF,YY 1000,SP,SP,XX 0FFC,XX 0FFD,8A 0FFE,4F 0FFF,YY 1000,7C 0FFC,30 0FFD,8A 0FFE,4F 0FFF,YY 1000,SP,(a)执行前 (b)PUSH AX后 (c)PUSH BX后,XX 0FFC XX 0FFC XX 0FFD XX 0FFD SP 8A 0FFE XX 0FFE4F 0FFF XX 0FFFYY 1000 SP YY 1000,(d)POP BX后 (e)POP AX后,注:XX表示栈空闲区填充的无用数据,YY表示栈中已存放的有效数据 图6.2 执行PUSH和POP指令对堆栈的影响,