Category:8086 Assembly: Difference between revisions
Content added Content deleted
Puppydrum64 (talk | contribs) m (added Ralf Brown's Interrupt List) |
Puppydrum64 (talk | contribs) m (ββThe Stack: explained how RET works) |
||
Line 63: | Line 63: | ||
<lang asm>push DS |
<lang asm>push DS |
||
pop ES ;you can't do "mov es, ds" but you can do this!</lang> |
pop ES ;you can't do "mov es, ds" but you can do this!</lang> |
||
The proper way to use the stack to preserve registers: |
|||
<lang asm> |
|||
call foo |
|||
mov ax,4C00h |
|||
int 21h ;exit program and return to DOS. Instruction pointer cannot move beyond this except with a function call. |
|||
foo: |
|||
push ax |
|||
push bx |
|||
push cx |
|||
pop cx |
|||
pop bx |
|||
pop ax |
|||
ret</lang> |
|||
If one of the push/pop commands in the routine above were missing, the <code>RET</code> instruction would not properly return to where it came from. As long as you pop at the end the same number of registers you pushed at the start, the stack is "balanced" and your return instruction will return correctly. This is because <code>RET</code> is actually <code>POP IP</code> (<code>IP</code> being the instruction pointer, which you can think of as what "line" of code the CPU is on.) The CPU assumes the top of the stack is the correct place to return to, but has no way of actually verifying it. If the function you just wrote causes the CPU to crash or jump to a completely different part of the code, there's a good chance you might have forgotten to balance the stack properly. |
|||
===Arithmetic=== |
===Arithmetic=== |