Assembly How to convert REP STOS to C code
Asked Answered
K

1

6

I been debugging REP STOS DWORD PTR ES:[EDI] for a while now

From my conclusion it always uses

ECX as counter. EAX as the value that will be copied over EDI and then appended ECX times so after putting in the pointed dump of EDI

it seems to overwrite the pointed data at EDI with what's it seems it always only uses ECX as a counter, while changing EDI by 4 bytes. it stops working when counter hits 0

So I came up with this kind of code

while(regs.d.ecx != 0)
{
    *(unsigned int *)(regs.d.edi) = regs.d.eax;
    regs.d.edi += 4;
    regs.d.ecx--;
}

Seems to work.. but i'm concerned since I just did this by luck and guess work. Is it solid? like will it always be ECX as counter, EAX as data, and it always copies 4 bytes never less?

Kampala answered 14/10, 2011 at 5:52 Comment(2)
found a duplicate https://mcmap.net/q/21776/-what-does-the-quot-rep-stos-quot-x86-assembly-instruction-sequence-do a bit to late.. seems everything is valid.Kampala
I recommend that you get AMD's programmer's manuals (vol 1 for intro, vol 3 for general-purpose instructions) as well as Intel's. Somehow I like better how the AMD's are structured and their tables. Intel's appear a bit more detailed.Mcginn
B
11

You are almost correct. The only difference is that the direction flag (DF) controls whether 4 is added or subtracted from EDI (and it actually is offset from the ES segment base, but you probably don't care about that):

for (; regs.d.ecx != 0; regs.d.ecx--)
{
    *(unsigned int *)(regs.d.edi) = regs.d.eax;
    regs.d.edi += regs.eflags.df ? -4 : 4;
}

Note that the for (; regs.d.ecx != 0; regs.d.ecx--) { } is the action of the REP prefix, and the body of the loop is the action of STOS DWORD....

Since you are asking a lot of these questions, I think you will find the Intel 64 and IA-32 Architectures Software Developer’s Manual, Volumes 2A and 2B to be useful. These contain descriptions of each instruction and prefix, including pseudo-code descriptions.

Baziotes answered 14/10, 2011 at 6:47 Comment(3)
There's more than DF. Depending on the CPU mode, STOSD may or may not need the operand size prefix (66h), which controls the element size (16 bits vs 32 bits, also AX vs EAX), the address size prefix (67h), which controls how many bits of EDI and ECX are used (16 vs 32). And, finally, it uses the ES segment register, meaning that the virtual address is ES.base + (E)DI. Oh, and it, of course, may cause an exception if the memory can't be written (read-only or not mapped or the privileges (CPL & RPL) aren't sufficient for the segment or underlying pages if page translation is enabled). :)Mcginn
blah i don't even understand how flags get generated from this.. well my emulator doesn't even have flags.. and so far so good!. :P, Hoping that stack + registers should be enoughKampala
@SSpoke: EFLAGS can be modelled as another register, some of whose bits are set by other instructions. For the DF flag there are specific instructions - STD sets it, and CLD clears it.Baziotes

© 2022 - 2024 — McMap. All rights reserved.