# Output from a debug script showing how PUSH places values on the stack # and POP gets them off again. # These comments (prefixed by '#') were added to the output file by # hand, to explain what is going on. -IAN! idallen@ncf.ca # First, fill memory with 2000h zeroes, to make things easier to see. -f 0100 l 2000 00 # Assemble a small program that puts 5678 at location 1234 and then # pushes both BX and [BX] on the stack. -a 0100 1426:0100 mov bx,1234 # load 1234 into BX 1426:0103 mov ax,5678 # load 5678 into AX 1426:0106 mov [bx],ax # store AX (5678) into memory location BX (1234) 1426:0108 push bx # push BX (1234) on the stack 1426:0109 push [bx] # push contents of memory location 1234 on stack 1426:010B pop CX # pop stack into CX 1426:010C pop DX # pop stack into DX 1426:010D nop # do nothing 1426:010E # Show registers. Trace two instructions and see values go into AX # and BX. The IP moves up by 3 bytes for each MOV instruction: -r AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=1426 ES=1426 SS=1426 CS=1426 IP=0100 NV UP EI PL NZ NA PO NC 1426:0100 BB3412 MOV BX,1234 -t AX=0000 BX=1234 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=1426 ES=1426 SS=1426 CS=1426 IP=0103 NV UP EI PL NZ NA PO NC 1426:0103 B87856 MOV AX,5678 -t AX=5678 BX=1234 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=1426 ES=1426 SS=1426 CS=1426 IP=0106 NV UP EI PL NZ NA PO NC 1426:0106 8907 MOV [BX],AX DS:1234=0000 # Show the contents of location 1234 before we move anything into it: -d 1230 l 10 1426:1230 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ # Trace one "store" instruction: MOV [BX],AX # This is only a two-byte instruction; the IP goes from 0106 to 0108 -t AX=5678 BX=1234 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=1426 ES=1426 SS=1426 CS=1426 IP=0108 NV UP EI PL NZ NA PO NC 1426:0108 53 PUSH BX # Show the contents of location 1234 again - see how 5678 got stored: -d 1230 l 10 1426:1230 00 00 00 00 78 56 00 00-00 00 00 00 00 00 00 00 ....xV.......... # In preparation for the PUSH, look at the stack area before the PUSH: -d ffe0 1426:FFE0 78 56 00 00 78 56 00 00-08 01 26 14 AB 0D 00 00 xV..xV....&..... 1426:FFF0 00 00 00 00 00 00 00 00-00 00 00 00 80 00 00 C0 ................ # Trace one instruction and note how the IP and SP registers change. # "PUSH BX" is a one-byte instruction - the IP goes up 1 from 0108 to 0109. # BX is a two-byte register - the SP goes down by 2 from FFEE to FFEC -t AX=5678 BX=1234 CX=0000 DX=0000 SP=FFEC BP=0000 SI=0000 DI=0000 DS=1426 ES=1426 SS=1426 CS=1426 IP=0109 NV UP EI PL NZ NA PO NC 1426:0109 FF37 PUSH [BX] DS:1234=5678 # Show the stack area again - see the value 1234 pushed at FFEC: -d ffe0 1426:FFE0 78 56 78 56 00 00 09 01-26 14 AB 0D 34 12 00 00 xVxV....&...4... 1426:FFF0 00 00 00 00 00 00 00 00-00 00 00 00 80 00 00 C0 ................ # Trace the next instruction and note how the IP and SP registers change. # "PUSH [BX]" is a two-byte instruction - the IP goes up 2 from 0109 to 010B. # We push 2 bytes of memory - the SP goes down by 2 from FFEC to FFEA -t AX=5678 BX=1234 CX=0000 DX=0000 SP=FFEA BP=0000 SI=0000 DI=0000 DS=1426 ES=1426 SS=1426 CS=1426 IP=010B NV UP EI PL NZ NA PO NC 1426:010B 59 POP CX # Show the stack area again - see the value 5678 pushed at FFEA, above # the previous value 1234: -d ffe0 1426:FFE0 78 56 00 00 0B 01 26 14-AB 0D 78 56 34 12 00 00 xV....&...xV4... 1426:FFF0 00 00 00 00 00 00 00 00-00 00 00 00 80 00 00 C0 ................ # Trace the two POP insructions. See the top value of the stack pop # into CX (5678) and the next value pop into DX (1234). # Each pop increases the SP by two bytes: FFEA -> FFEC -> FFEE -t AX=5678 BX=1234 CX=5678 DX=0000 SP=FFEC BP=0000 SI=0000 DI=0000 DS=1426 ES=1426 SS=1426 CS=1426 IP=010C NV UP EI PL NZ NA PO NC 1426:010C 5A POP DX -t AX=5678 BX=1234 CX=5678 DX=1234 SP=FFEE BP=0000 SI=0000 DI=0000 DS=1426 ES=1426 SS=1426 CS=1426 IP=010D NV UP EI PL NZ NA PO NC 1426:010D 90 NOP # That's all! -q