Zebediah Figura z.figura12@gmail.com writes:
+static LONGLONG _alldvrm_wrapper(LARGE_INTEGER a, LARGE_INTEGER b, LARGE_INTEGER *rem) +{
- /* _alldvrm() divides two LONGLONGs and returns the quotient in edx:eax and
* the remainder in ebx:ecx. */
- LONGLONG ret;
- __asm__ __volatile__ (
"pushl %%ebx\n\t"
"pushl %3\n\t"
"pushl %4\n\t"
"pushl %5\n\t"
"pushl %6\n\t"
"call *%7\n\t"
"movl %%ebx, %1\n\t"
"movl %%ecx, %2\n\t"
"popl %%ebx\n\t"
: "=A" (ret), "=r" (rem->HighPart), "=r" (rem->LowPart)
: "ri" (b.HighPart), "ri" (b.LowPart), "ri" (a.HighPart), "ri" (a.LowPart), "m" (p_alldvrm)
: "ebx", "ecx"
- );
That sort of assembly with a million register constraints is fragile, and will most likely break depending on optimization options.
- /* _alldvrm(0x0123456701234567, 3) */
- a.HighPart = a.LowPart = 0x01234567;
- b.QuadPart = 3;
- ret = _alldvrm_wrapper(a, b, &rem);
- ok(ret == 0x61172255b66c77ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
Please avoid long long constants.