翻译C++ x86内联汇编代码为c++
我一直在努力将此装配代码转换为C ++代码。
这是一个旧游戏的函数,该功能采用Pixel Data STMP
,我相信它将其置于目标void* dest
void Function(int x, int y, int yl, void* Stmp, void* dest)
{
unsigned long size = 1280 * 2;
unsigned long j = yl;
void* Dtmp = (void*)((char*)dest + y * size + (x * 2));
_asm
{
push es;
push ds;
pop es;
mov edx,Dtmp;
mov esi,Stmp;
mov ebx,j;
xor eax,eax;
xor ecx,ecx;
loop_1:
or bx,bx;
jz exit_1;
mov edi,edx;
loop_2:
cmp word ptr[esi],0xffff;
jz exit_2;
mov ax,[esi];
add edi,eax;
mov cx,[esi+2];
add esi,4;
shr ecx,2;
jnc Next2;
movsw;
Next2:
rep movsd;
jmp loop_2;
exit_2:
add esi,2;
add edx,size;
dec bx;
jmp loop_1;
exit_1:
pop es;
};
}
这是我到达的地方:当然,是否正确),
while (j > 0)
{
if (*stmp != 0xffff)
{
}
++stmp;
dtmp += size;
--j;
}
非常感谢任何帮助。谢谢。
I've been struggling trying to convert this assembly code to C++ code.
It's a function from an old game that takes pixel data Stmp
, and I believe it places it to destination void* dest
void Function(int x, int y, int yl, void* Stmp, void* dest)
{
unsigned long size = 1280 * 2;
unsigned long j = yl;
void* Dtmp = (void*)((char*)dest + y * size + (x * 2));
_asm
{
push es;
push ds;
pop es;
mov edx,Dtmp;
mov esi,Stmp;
mov ebx,j;
xor eax,eax;
xor ecx,ecx;
loop_1:
or bx,bx;
jz exit_1;
mov edi,edx;
loop_2:
cmp word ptr[esi],0xffff;
jz exit_2;
mov ax,[esi];
add edi,eax;
mov cx,[esi+2];
add esi,4;
shr ecx,2;
jnc Next2;
movsw;
Next2:
rep movsd;
jmp loop_2;
exit_2:
add esi,2;
add edx,size;
dec bx;
jmp loop_1;
exit_1:
pop es;
};
}
That's where I've gotten as far to: (Not sure if it's even correct)
while (j > 0)
{
if (*stmp != 0xffff)
{
}
++stmp;
dtmp += size;
--j;
}
Any help is greatly appreciated. Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它保存/还原设置等于DS MOVSD 将使用相同的地址进行负载和存储。该指令基本上是
memcpy(EDI,ESI,ECX)
,但会增加EDI和ESI中的指针(由4 * ECX)。 movsw:movsd:movsq在平坦的内存模型中,您可以完全忽略它。该代码看起来可能已经写成以16位虚幻模式或甚至实际模式运行,因此到处都有16位寄存器的使用。
看起来像是加载了某种记录,这些记录要阐明要复制多少个字节,并读取直到记录结束,此时它会在其中查找下一个记录。周围有一个外循环,通过记录循环。
我认为的记录看起来像:
内部循环是:
旧的CPU(ivybridge之前)的
rep movsd
比rep movsb
更快,否则此代码只能做到这一点。这是一个过时的成语,来自8080,用于
测试BX,BX
/JNZ
,即如果Bx为零,则跳转。因此,它是while(bx!= 0){}
循环。使用DEC BX
。这是编写的一种低效方法,而(-bx)
loop;编译器会将DEC
/JNZ .TOP_OF_LOOP
放在底部,一次测试在循环外面一次,以防其运行零次。 Why are loops always compiled into "do.. 。
It saves / restores ES around setting it equal to DS so
rep movsd
will use the same addresses for load and store. That instruction is basicallymemcpy(edi, esi, ecx)
but incrementing the pointers in EDI and ESI (by 4 * ecx). https://www.felixcloutier.com/x86/movs:movsb:movsw:movsd:movsqIn a flat memory model, you can totally ignore that. This code looks like it might have been written to run in 16-bit unreal mode, or possibly even real mode, hence the use of 16-bit registers all over the place.
Look like it's loading some kind of records that tell it how many bytes to copy, and reading until the end of the record, at which point it looks for the next record there. There's an outer loop around that, looping through records.
The records look like this I think:
The inner loop is this:
Old CPUs (before IvyBridge) had
rep movsd
faster thanrep movsb
, otherwise this code could just have done that.That's an obsolete idiom that comes from 8080 for
test bx,bx
/jnz
, i.e. jump if BX was zero. So it's awhile( bx != 0 ) {}
loop. Withdec bx
in it. It's an inefficient way to write awhile (--bx)
loop; a compiler would put adec
/jnz .top_of_loop
at the bottom, with a test once outside the loop in case it needs to run zero times. Why are loops always compiled into "do...while" style (tail jump)?Some people would say that's what a
while
loop looks like in asm, if they're picturing totally naive translation from C to asm.