开发者

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

thanks in advance.


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...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜