汇编如何将REP STO转换为C代码
我已经调试了一段时间了 从我的结论来看,它总是使用汇编如何将REP STO转换为C代码,c,assembly,x86,machine-code,code-translation,C,Assembly,X86,Machine Code,Code Translation,我已经调试了一段时间了 从我的结论来看,它总是使用 ECX作为计数器。 EAX作为将在EDI上复制的值,然后追加ECX次 因此,在放入EDI的定点转储后 它似乎覆盖了EDI上的指向数据 似乎它总是只使用ECX作为计数器,而将EDI更改了4个字节。 当计数器达到0时,它停止工作 所以我想出了这种代码 while(regs.d.ecx != 0) { *(unsigned int *)(regs.d.edi) = regs.d.eax; regs.d.edi += 4; re
ECX
作为计数器。
EAX
作为将在EDI
上复制的值,然后追加ECX
次
因此,在放入EDI的定点转储后
它似乎覆盖了EDI上的指向数据
似乎它总是只使用ECX作为计数器,而将EDI更改了4个字节。
当计数器达到0时,它停止工作
所以我想出了这种代码
while(regs.d.ecx != 0)
{
*(unsigned int *)(regs.d.edi) = regs.d.eax;
regs.d.edi += 4;
regs.d.ecx--;
}
似乎有用。。但我很担心,因为我只是靠运气和猜测工作。它是固体的吗?就像它总是将
ECX
作为计数器,将EAX
作为数据,并且它总是复制4个字节,从来没有少过?你几乎是正确的。唯一的区别是方向标志(DF
)控制是从EDI
中添加还是减去4(它实际上是从ES
段基偏移的,但您可能并不关心这一点):
请注意,(;regs.d.ecx!=0;regs.d.ecx--){}的是REP
前缀的动作,循环体是STOS DWORD…
的动作
既然你问了很多这样的问题,我想你会发现这本书很有用。这些包含每个指令和前缀的描述,包括伪代码描述。发现一个重复的有点晚。。似乎一切都是有效的。我建议你得到AMD的程序员手册(第一卷介绍,第三卷通用说明)以及英特尔的。不知何故,我更喜欢AMD的结构和表格。英特尔的数据看起来更详细一些,不仅仅是DF。根据CPU模式的不同,STOSD可能需要也可能不需要操作数大小前缀(66h),它控制元素大小(16位对32位,也包括AX对EAX),地址大小前缀(67h),它控制使用的EDI和ECX的位数(16位对32位)。最后,它使用ES段寄存器,这意味着虚拟地址是ES.base+(E)DI。哦,当然,如果内存无法写入(只读或未映射,或者如果启用页转换,则权限(CPL&RPL)对于段或底层页是不够的),它可能会导致异常:)诸如此类,我甚至不明白如何从中生成标志。。我的模拟器甚至没有标志。。到目前为止,一切都很好P、 希望堆栈+寄存器应该是enough@SSpoke:EFLAGS
可以建模为另一个寄存器,其中一些位由其他指令设置。对于DF
标志,有特定的说明-STD
设置它,而CLD
清除它。
for (; regs.d.ecx != 0; regs.d.ecx--)
{
*(unsigned int *)(regs.d.edi) = regs.d.eax;
regs.d.edi += regs.eflags.df ? -4 : 4;
}