基于索引模式到间接寻址模式的转换(x86汇编) [英] Transformation of based indexed mode into indirect addressing mode (x86 assembly)

查看:31
本文介绍了基于索引模式到间接寻址模式的转换(x86汇编)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正致力于将示例从复杂的间接寻址模式更改为简单的间接寻址模式片段.但是,我遇到了一个来自基本模式的例子,我无法转换".

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

代码:

move %eax, 28(%esp)

我试过了

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)

-> 进入

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

然而这是有效的,但它稍微改变了我的输出,所以它也可能不正确.

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

推荐答案

免责声明:我不喜欢 AT&T 语法,所以如果以下描述的内容与您想要做的完全相反,我就把它搞砸了并且您需要转换参数(从我的的角度来看,与指令的意图相反,这与我的意思相反> 它,但似乎做了另一件事......等等,我想我把自己扭在了一个角落里).

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

正如@nrz 所评论的那样,修改 ESP 本身可能会使您的函数稍后在尝试通过使用 ret 将其返回地址从堆栈中弹出来返回时崩溃.

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.

类似地,

cmpl  $4, 28(%esp)

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

注意这个指令序列改变了 %eax 而原来的单条指令没有.这是有原因的:提供间接指针操作因为它们不需要中间寄存器.(而且因为它们节省了指令,增加了每条指令和每字节代码可以完成的工作量.)

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

在 Z80 等较旧的 CPU 中,确实不得不通过手动"加载一个寄存器作为基址,添加偏移量,然后加载目标值来进行间接寻址.

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.

这篇关于基于索引模式到间接寻址模式的转换(x86汇编)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆