captainys / TOWNSEMU

FM Towns Emulator "Tsugaru"
BSD 3-Clause "New" or "Revised" License
238 stars 17 forks source link

fix j(e)cxz, loop((n)e) prefix #61

Closed pinterior closed 1 year ago

pinterior commented 1 year ago

for LOOP-like instructions, use address size prefix to determine which register to use, CX or ECX.

#include <stdio.h>

int loop32(int x) {
   // mov ecx, [esp + 4]
   _inline(0x8b, 0x4c, 0x24, 0x04);
   // loop $
   _inline(0xe2, 0xfe);
   // mov eax, ecx
   _inline(0x89, 0xc8);
}

int loop16(int x) {
   // mov ecx, [esp + 4]
   _inline(0x8b, 0x4c, 0x24, 0x04);
   // loop $
   _inline(0x67, 0xe2, 0xfd);
   // mov eax, ecx
   _inline(0x89, 0xc8);
}

int main(int argc, char *argv[]) {
   printf("32: %08x\n", loop32(0x10001));
   printf("16: %08x\n", loop16(0x10001));
   return 0;
}

should output:

32: 00000000
16: 00010000
captainys commented 1 year ago

Is that right!? I was thinking it should be operand size, not address size. Thank you for finding it. I'll take a look.

pinterior commented 1 year ago

it's very confusing. to specify EIP clipping and register reference independently, ISA designer used two prefixes here I think.

captainys commented 1 year ago

Thanks! I hope it pushes Windows 3.1 a bit further into the boot sequence! I'll see.