Transformation of based indexed mode into indirect addressing mode (x86 assembly)

▼魔方 西西 提交于 2019-12-04 05:10:41

问题


I'm corrently working on changing examples from complex indirect addresssing mode into simple indirect addressing mode pieces. However, I've come across an example from the Based Mode, I'm unable to "transform".

Code:

move %eax, 28(%esp)

I've tried

addl    $28, %esp
movl    (%eax), %esp

This creates a segmentation fault; and I've no idea how else I should write it.

Another example, I've failed to "transform is

compl $4, 28(%esp)

-> into

addl    $28, %esp
cmpl    $4, %esp

However this is working, but it changes my output slightly, so it might not be correct as well.


回答1:


Disclaimer: I am no fan of the AT&T syntax so if the following seems to describe exactly the opposite of what you wanted to do, I messed it up and you need to switch the arguments around (to, from my point of view, the opposite of what the instructions are meant to do, which is then the opposite of what I meant it to but appears to do the other thing ... wait, I think I twisted myself in a corner here).

(Editor's note: yes, this was backwards, e.g. loading instead of storing, and at least one backwards operand other than that. Fixed now.)


mov  %eax, 28(%esp)     # store EAX to memory at ESP+28

You need a scratch register to calculate the store address in. If you were loading, you could calculate in the destination register, but for a store we need the original data and the address. This is one reason addressing modes are so convenient.

mov %esp, %ecx       # copy ESP to ECX
add $28, %ecx        # modify the tmp copy, not the stack pointer
mov %eax, (%ecx)     # store EAX into memory dword pointed to by ECX

As @nrz commented, modifying ESP itself will likely make your function crash later when it tries to return by popping its return address off the stack with ret.


Similarly, a small-steps variant of

cmpl  $4, 28(%esp)

is

mov   %esp, %eax
add   $28, %eax
cmpl  $4, (%eax)     # compare immediate with dword pointed to by EAX

or, if that last line is too complicated (because also indirect),

mov (%eax), %eax
cmp $4, %eax         # dword operand size (cmpl) implied by the register

Note that this instruction sequence alters %eax whereas the original single instruction does not. There is a reason for that: indirect pointer operations are provided because they do not need intermediate registers. (And because they save instructions, increasing the amount of work you can get done per instruction and per byte of code.)

In older CPUs such as the Z80, one indeed had to do indirect addressing by "manually" loading a register as base, adding the offset, then loading the target value.




回答2:


Example 1:

This:

addl    $28, %esp
movl    (%eax), %esp

doesn't do the same thing as move %eax, 28(%esp). What you're looking for is something like:

addl    $28, %esp
movl    %eax, (%esp)

But note that your version modifies the value of esp, while the original instruction does not.


Example 2:

Again, this:

addl    $28, %esp
cmpl    $4, %esp

doesn't do the same thing as cmpl $4, 28(%esp). The original instruction compares the 32-bit value in memory at address esp+28 with the value 4. Your version compares the value esp+28 with the value 4 (i.e. there's no memory access).



来源:https://stackoverflow.com/questions/30222844/transformation-of-based-indexed-mode-into-indirect-addressing-mode-x86-assembly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!