8086 Assembly question, what does this code do
i've received this question in my assembly course:
what does this procedure do
and how it should be called?push 开发者_开发问答ebp
mov ebp, esp
push esi
mov esi, [ebp+4]
mov eax, [esi]
sub eax, [esi+4]
add esi, 8
mov [ebp+4], esi
pop esi
pop ebp
ret
it looks like [ebp+4]
is an argument and not the return address, so it should be called with "jmp" and not "call".
i don't really understand what should be found on [esi+4]
and on esi+8
(the return address)
hmm, i'm really confused, hope you can help me
As you rightfully note, if this routine is called with a call
then [ebp+4]
is the return address. That does not mean that this is a bad idea.
Assume that the routine is called with a call
. At that point, the "return address" which is pushed on the stack is the address of the byte which immediately follows the call
opcode. Let's call this address x. The routine then extracts from address x two 32-bit words, one at address x and one at address x+4. It subtracts the second word from the first one, storing the result in eax
. Finally, the routine stores back the value x+8 in the stack slot [ebp+4]
, the net effect being that when the ret
is reached, execution resumes at address x+8. With this hypothesis, the routine looks like a way to subtract integers which are located in the middle of the code, something like this:
call yourroutine
dd 56478634
dd 18943675
mov ebx, eax ; an example instruction
Here, the call
returns to the mov
instruction, and at that point eax
contains the value 37534959 (that's 18943675 subtracted from 56478634).
As a code routine, it is not terribly useful, since it is a convoluted way to load eax
with a constant value which is hardcoded (code space is normally read-only during execution). One might imagine that such a routine could appear as part of the runtime support for dynamic linkage on some architecture (dynamic linkage is a hairy subject).
Now, let's assume, instead, that the routine is invoked with a jmp
. [ebp+4]
now designates whatever was on top of stack at that point. The routine takes that value (let's call it y), get the two words at addresses y and y+4, computes the subtraction result into eax
, and then stores y+8 back into the [ebp+4]
slot. Finally, the ret
interprets that slot as a return address, i.e. the address of some code to which execution should jump. It does not matter that no call
opcode was involved in the production of that address; ret
will jump to it nonetheless. This time, the invocation code may look like:
push foobar
jmp yourroutine
... ; unreached code
foobar:
dd 56478634
dd 18943675
mov ebx, eax ; an example instruction
This time, this looks like a parameterized jump with some inherent loading of eax
. Code like that can exist in the implementation of some interpreters for threaded code. As a homework question, however, I am quite sure that this was not what was intended (threaded code interpreters are even hairier than dynamic linking).
No, it should definitely be called with call
- it has a ret
at the end.
In terms of what it does, you should sit down with a piece of paper with a list of the registers and single-step that code through your head, updating the registers as you go. Then it should be obvious what's going on:
eax:
esp:
ebp:
esi:
as well as other relevant memory (such as the area around the stack top).
This is an ideal way to learn about programming (for small programs anyway) in that you learn to analyse things in detail and actually understand them. And I'm afraid that's about as much help as I'm going to give for a homework assignment :-)
When you do a call to this function, the return address (eip of address of instruction after call) is pushed onto the stack, and after the first function preamble, [ebp+4]
references that return address. The body of the function then considers this address as 2 integers, that are substracted, result put in eax
and then the return address is incremented by 8, i.e. the size of these 2 integers by add esi,8
and mov [ebp+4], esi
. The ret
just puts us back at that new return address (which hopefully is a valid instruction....).
A weird function, looks in place in some self modifying code etc...
精彩评论