You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
7.7 KiB

/*
* Copyright 2002-2019 Intel Corporation.
*
* This software is provided to you as Sample Source Code as defined in the accompanying
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
* section 1.L.
*
* This software and the related documents are provided as is, with no express or implied
* warranties, other than those that are expressly stated in the License.
*/
/*
* This test verifies that Pin correctly translates PUSHA and POPA
* instructions (both 32- and 16-bit variants).
*/
#include <iostream>
#include <string.h>
#ifdef _MSC_VER
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#else
#include <stdint.h>
#endif
typedef uint16_t UINT16;
typedef uint32_t UINT32;
#ifdef TARGET_WINDOWS
#define ASMNAME(name)
#else
#define ASMNAME(name) asm(name)
#endif
struct REGS16
{
UINT16 ax;
UINT16 cx;
UINT16 dx;
UINT16 bx;
UINT16 sp;
UINT16 bp;
UINT16 si;
UINT16 di;
};
struct REGS32
{
UINT32 eax;
UINT32 ecx;
UINT32 edx;
UINT32 ebx;
UINT32 esp;
UINT32 ebp;
UINT32 esi;
UINT32 edi;
};
static bool TestPushA16();
static bool TestPopA16();
static bool TestPushA32();
static bool TestPopA32();
extern "C" void DoPushA16(const REGS16 *, REGS16 *, UINT16 *) ASMNAME("DoPushA16");
extern "C" void DoPopA16(const REGS16 *, REGS16 *) ASMNAME("DoPopA16");
extern "C" void DoPushA32(const REGS32 *, REGS32 *, UINT32 *) ASMNAME("DoPushA32");
extern "C" void DoPopA32(const REGS32 *, REGS32 *) ASMNAME("DoPopA32");
int main(int argc, char * argv[])
{
if (!TestPushA16())
return 1;
if (!TestPopA16())
return 1;
if (!TestPushA32())
return 1;
if (!TestPopA32())
return 1;
return 0;
}
static bool TestPushA16()
{
REGS16 inRegs;
REGS16 outRegs;
UINT16 inSp;
inRegs.ax = 1;
inRegs.cx = 2;
inRegs.dx = 3;
inRegs.bx = 4;
inRegs.sp = 0;
inRegs.bp = 6;
inRegs.si = 7;
inRegs.di = 8;
memset(&outRegs, 0, sizeof(outRegs));
DoPushA16(&inRegs, &outRegs, &inSp);
if (outRegs.ax != inRegs.ax)
{
std::cout << "PushA16 AX mismatch " << inRegs.ax << " -> " << outRegs.ax << "\n";
return false;
}
if (outRegs.cx != inRegs.cx)
{
std::cout << "PushA16 CX mismatch " << inRegs.cx << " -> " << outRegs.cx << "\n";
return false;
}
if (outRegs.dx != inRegs.dx)
{
std::cout << "PushA16 DX mismatch " << inRegs.dx << " -> " << outRegs.dx << "\n";
return false;
}
if (outRegs.bx != inRegs.bx)
{
std::cout << "PushA16 BX mismatch " << inRegs.bx << " -> " << outRegs.bx << "\n";
return false;
}
if (outRegs.bp != inRegs.bp)
{
std::cout << "PushA16 BP mismatch " << inRegs.bp << " -> " << outRegs.bp << "\n";
return false;
}
if (outRegs.si != inRegs.si)
{
std::cout << "PushA16 SI mismatch " << inRegs.si << " -> " << outRegs.si << "\n";
return false;
}
if (outRegs.di != inRegs.di)
{
std::cout << "PushA16 DI mismatch " << inRegs.di << " -> " << outRegs.di << "\n";
return false;
}
if (outRegs.sp != inSp)
{
std::cout << "PushA16 SP mismatch " << inSp << " -> " << outRegs.sp << "\n";
return false;
}
return true;
}
static bool TestPopA16()
{
REGS16 inRegs;
REGS16 outRegs;
inRegs.ax = 1;
inRegs.cx = 2;
inRegs.dx = 3;
inRegs.bx = 4;
inRegs.sp = 0;
inRegs.bp = 6;
inRegs.si = 7;
inRegs.di = 8;
memset(&outRegs, 0, sizeof(outRegs));
DoPopA16(&inRegs, &outRegs);
if (outRegs.ax != inRegs.ax)
{
std::cout << "PopA16 AX mismatch " << inRegs.ax << " -> " << outRegs.ax << "\n";
return false;
}
if (outRegs.cx != inRegs.cx)
{
std::cout << "PopA16 CX mismatch " << inRegs.cx << " -> " << outRegs.cx << "\n";
return false;
}
if (outRegs.dx != inRegs.dx)
{
std::cout << "PopA16 DX mismatch " << inRegs.dx << " -> " << outRegs.dx << "\n";
return false;
}
if (outRegs.bx != inRegs.bx)
{
std::cout << "PopA16 BX mismatch " << inRegs.bx << " -> " << outRegs.bx << "\n";
return false;
}
if (outRegs.bp != inRegs.bp)
{
std::cout << "PopA16 BP mismatch " << inRegs.bp << " -> " << outRegs.bp << "\n";
return false;
}
if (outRegs.si != inRegs.si)
{
std::cout << "PopA16 SI mismatch " << inRegs.si << " -> " << outRegs.si << "\n";
return false;
}
if (outRegs.di != inRegs.di)
{
std::cout << "PopA16 DI mismatch " << inRegs.di << " -> " << outRegs.di << "\n";
return false;
}
return true;
}
static bool TestPushA32()
{
REGS32 inRegs;
REGS32 outRegs;
UINT32 inSp;
inRegs.eax = 1;
inRegs.ecx = 2;
inRegs.edx = 3;
inRegs.ebx = 4;
inRegs.esp = 0;
inRegs.ebp = 6;
inRegs.esi = 7;
inRegs.edi = 8;
memset(&outRegs, 0, sizeof(outRegs));
DoPushA32(&inRegs, &outRegs, &inSp);
if (outRegs.eax != inRegs.eax)
{
std::cout << "PushA32 AX mismatch " << inRegs.eax << " -> " << outRegs.eax << "\n";
return false;
}
if (outRegs.ecx != inRegs.ecx)
{
std::cout << "PushA32 CX mismatch " << inRegs.ecx << " -> " << outRegs.ecx << "\n";
return false;
}
if (outRegs.edx != inRegs.edx)
{
std::cout << "PushA32 DX mismatch " << inRegs.edx << " -> " << outRegs.edx << "\n";
return false;
}
if (outRegs.ebx != inRegs.ebx)
{
std::cout << "PushA32 BX mismatch " << inRegs.ebx << " -> " << outRegs.ebx << "\n";
return false;
}
if (outRegs.ebp != inRegs.ebp)
{
std::cout << "PushA32 BP mismatch " << inRegs.ebp << " -> " << outRegs.ebp << "\n";
return false;
}
if (outRegs.esi != inRegs.esi)
{
std::cout << "PushA32 SI mismatch " << inRegs.esi << " -> " << outRegs.esi << "\n";
return false;
}
if (outRegs.edi != inRegs.edi)
{
std::cout << "PushA32 DI mismatch " << inRegs.edi << " -> " << outRegs.edi << "\n";
return false;
}
if (outRegs.esp != inSp)
{
std::cout << "PushA32 SP mismatch " << inSp << " -> " << outRegs.esp << "\n";
return false;
}
return true;
}
static bool TestPopA32()
{
REGS32 inRegs;
REGS32 outRegs;
inRegs.eax = 1;
inRegs.ecx = 2;
inRegs.edx = 3;
inRegs.ebx = 4;
inRegs.esp = 0;
inRegs.ebp = 6;
inRegs.esi = 7;
inRegs.edi = 8;
memset(&outRegs, 0, sizeof(outRegs));
DoPopA32(&inRegs, &outRegs);
if (outRegs.eax != inRegs.eax)
{
std::cout << "PopA32 AX mismatch " << inRegs.eax << " -> " << outRegs.eax << "\n";
return false;
}
if (outRegs.ecx != inRegs.ecx)
{
std::cout << "PopA32 CX mismatch " << inRegs.ecx << " -> " << outRegs.ecx << "\n";
return false;
}
if (outRegs.edx != inRegs.edx)
{
std::cout << "PopA32 DX mismatch " << inRegs.edx << " -> " << outRegs.edx << "\n";
return false;
}
if (outRegs.ebx != inRegs.ebx)
{
std::cout << "PopA32 BX mismatch " << inRegs.ebx << " -> " << outRegs.ebx << "\n";
return false;
}
if (outRegs.ebp != inRegs.ebp)
{
std::cout << "PopA32 BP mismatch " << inRegs.ebp << " -> " << outRegs.ebp << "\n";
return false;
}
if (outRegs.esi != inRegs.esi)
{
std::cout << "PopA32 SI mismatch " << inRegs.esi << " -> " << outRegs.esi << "\n";
return false;
}
if (outRegs.edi != inRegs.edi)
{
std::cout << "PopA32 DI mismatch " << inRegs.edi << " -> " << outRegs.edi << "\n";
return false;
}
return true;
}