📄 test-i386.c
字号:
void test_bcd(void){ TEST_BCD(daa, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(daa, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(daa, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(daa, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(daa, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(daa, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(daa, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(daa, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(daa, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(daa, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(daa, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(daa, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(daa, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(das, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); TEST_BCD(aaa, 0x12340205, CC_A, (CC_C | CC_A)); TEST_BCD(aaa, 0x12340306, CC_A, (CC_C | CC_A)); TEST_BCD(aaa, 0x1234040a, CC_A, (CC_C | CC_A)); TEST_BCD(aaa, 0x123405fa, CC_A, (CC_C | CC_A)); TEST_BCD(aaa, 0x12340205, 0, (CC_C | CC_A)); TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A)); TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A)); TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A)); TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A)); TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A)); TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A)); TEST_BCD(aas, 0x123405fa, CC_A, (CC_C | CC_A)); TEST_BCD(aas, 0x12340205, 0, (CC_C | CC_A)); TEST_BCD(aas, 0x12340306, 0, (CC_C | CC_A)); TEST_BCD(aas, 0x1234040a, 0, (CC_C | CC_A)); TEST_BCD(aas, 0x123405fa, 0, (CC_C | CC_A)); TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));}#endif#define TEST_XCHG(op, size, opconst)\{\ long op0, op1;\ op0 = i2l(0x12345678);\ op1 = i2l(0xfbca7654);\ asm(#op " %" size "0, %" size "1" \ : "=q" (op0), opconst (op1) \ : "0" (op0), "1" (op1));\ printf("%-10s A=" FMTLX " B=" FMTLX "\n",\ #op, op0, op1);\}#define TEST_CMPXCHG(op, size, opconst, eax)\{\ long op0, op1, op2;\ op0 = i2l(0x12345678);\ op1 = i2l(0xfbca7654);\ op2 = i2l(eax);\ asm(#op " %" size "0, %" size "1" \ : "=q" (op0), opconst (op1) \ : "0" (op0), "1" (op1), "a" (op2));\ printf("%-10s EAX=" FMTLX " A=" FMTLX " C=" FMTLX "\n",\ #op, op2, op0, op1);\}void test_xchg(void){#if defined(__x86_64__) TEST_XCHG(xchgq, "", "=q");#endif TEST_XCHG(xchgl, "k", "=q"); TEST_XCHG(xchgw, "w", "=q"); TEST_XCHG(xchgb, "b", "=q");#if defined(__x86_64__) TEST_XCHG(xchgq, "", "=m");#endif TEST_XCHG(xchgl, "k", "=m"); TEST_XCHG(xchgw, "w", "=m"); TEST_XCHG(xchgb, "b", "=m");#if defined(__x86_64__) TEST_XCHG(xaddq, "", "=q");#endif TEST_XCHG(xaddl, "k", "=q"); TEST_XCHG(xaddw, "w", "=q"); TEST_XCHG(xaddb, "b", "=q"); { int res; res = 0x12345678; asm("xaddl %1, %0" : "=r" (res) : "0" (res)); printf("xaddl same res=%08x\n", res); }#if defined(__x86_64__) TEST_XCHG(xaddq, "", "=m");#endif TEST_XCHG(xaddl, "k", "=m"); TEST_XCHG(xaddw, "w", "=m"); TEST_XCHG(xaddb, "b", "=m");#if defined(__x86_64__) TEST_CMPXCHG(cmpxchgq, "", "=q", 0xfbca7654);#endif TEST_CMPXCHG(cmpxchgl, "k", "=q", 0xfbca7654); TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654); TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654);#if defined(__x86_64__) TEST_CMPXCHG(cmpxchgq, "", "=q", 0xfffefdfc);#endif TEST_CMPXCHG(cmpxchgl, "k", "=q", 0xfffefdfc); TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc); TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc);#if defined(__x86_64__) TEST_CMPXCHG(cmpxchgq, "", "=m", 0xfbca7654);#endif TEST_CMPXCHG(cmpxchgl, "k", "=m", 0xfbca7654); TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654); TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654);#if defined(__x86_64__) TEST_CMPXCHG(cmpxchgq, "", "=m", 0xfffefdfc);#endif TEST_CMPXCHG(cmpxchgl, "k", "=m", 0xfffefdfc); TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc); TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc); { uint64_t op0, op1, op2; long i, eflags; for(i = 0; i < 2; i++) { op0 = 0x123456789abcd; if (i == 0) op1 = 0xfbca765423456; else op1 = op0; op2 = 0x6532432432434; asm("cmpxchg8b %1\n" "pushf\n" "pop %2\n" : "=A" (op0), "=m" (op1), "=g" (eflags) : "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32))); printf("cmpxchg8b: op0=" FMT64X " op1=" FMT64X " CC=%02lx\n", op0, op1, eflags & CC_Z); } }}#ifdef TEST_SEGS/**********************************************//* segmentation tests */#include <asm/ldt.h>#include <linux/unistd.h>#include <linux/version.h>_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)#define modify_ldt_ldt_s user_desc#endif#define MK_SEL(n) (((n) << 3) | 7)uint8_t seg_data1[4096];uint8_t seg_data2[4096];#define TEST_LR(op, size, seg, mask)\{\ int res, res2;\ res = 0x12345678;\ asm (op " %" size "2, %" size "0\n" \ "movl $0, %1\n"\ "jnz 1f\n"\ "movl $1, %1\n"\ "1:\n"\ : "=r" (res), "=r" (res2) : "m" (seg), "0" (res));\ printf(op ": Z=%d %08x\n", res2, res & ~(mask));\}/* NOTE: we use Linux modify_ldt syscall */void test_segs(void){ struct modify_ldt_ldt_s ldt; long long ldt_table[3]; int res, res2; char tmp; struct { uint32_t offset; uint16_t seg; } __attribute__((packed)) segoff; ldt.entry_number = 1; ldt.base_addr = (unsigned long)&seg_data1; ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12; ldt.seg_32bit = 1; ldt.contents = MODIFY_LDT_CONTENTS_DATA; ldt.read_exec_only = 0; ldt.limit_in_pages = 1; ldt.seg_not_present = 0; ldt.useable = 1; modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ ldt.entry_number = 2; ldt.base_addr = (unsigned long)&seg_data2; ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12; ldt.seg_32bit = 1; ldt.contents = MODIFY_LDT_CONTENTS_DATA; ldt.read_exec_only = 0; ldt.limit_in_pages = 1; ldt.seg_not_present = 0; ldt.useable = 1; modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */#if 0 { int i; for(i=0;i<3;i++) printf("%d: %016Lx\n", i, ldt_table[i]); }#endif /* do some tests with fs or gs */ asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); seg_data1[1] = 0xaa; seg_data2[1] = 0x55; asm volatile ("fs movzbl 0x1, %0" : "=r" (res)); printf("FS[1] = %02x\n", res); asm volatile ("pushl %%gs\n" "movl %1, %%gs\n" "gs movzbl 0x1, %0\n" "popl %%gs\n" : "=r" (res) : "r" (MK_SEL(2))); printf("GS[1] = %02x\n", res); /* tests with ds/ss (implicit segment case) */ tmp = 0xa5; asm volatile ("pushl %%ebp\n\t" "pushl %%ds\n\t" "movl %2, %%ds\n\t" "movl %3, %%ebp\n\t" "movzbl 0x1, %0\n\t" "movzbl (%%ebp), %1\n\t" "popl %%ds\n\t" "popl %%ebp\n\t" : "=r" (res), "=r" (res2) : "r" (MK_SEL(1)), "r" (&tmp)); printf("DS[1] = %02x\n", res); printf("SS[tmp] = %02x\n", res2); segoff.seg = MK_SEL(2); segoff.offset = 0xabcdef12; asm volatile("lfs %2, %0\n\t" "movl %%fs, %1\n\t" : "=r" (res), "=g" (res2) : "m" (segoff)); printf("FS:reg = %04x:%08x\n", res2, res); TEST_LR("larw", "w", MK_SEL(2), 0x0100); TEST_LR("larl", "", MK_SEL(2), 0x0100); TEST_LR("lslw", "w", MK_SEL(2), 0); TEST_LR("lsll", "", MK_SEL(2), 0); TEST_LR("larw", "w", 0xfff8, 0); TEST_LR("larl", "", 0xfff8, 0); TEST_LR("lslw", "w", 0xfff8, 0); TEST_LR("lsll", "", 0xfff8, 0);}/* 16 bit code test */extern char code16_start, code16_end;extern char code16_func1;extern char code16_func2;extern char code16_func3;void test_code16(void){ struct modify_ldt_ldt_s ldt; int res, res2; /* build a code segment */ ldt.entry_number = 1; ldt.base_addr = (unsigned long)&code16_start; ldt.limit = &code16_end - &code16_start; ldt.seg_32bit = 0; ldt.contents = MODIFY_LDT_CONTENTS_CODE; ldt.read_exec_only = 0; ldt.limit_in_pages = 0; ldt.seg_not_present = 0; ldt.useable = 1; modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ /* call the first function */ asm volatile ("lcall %1, %2" : "=a" (res) : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc"); printf("func1() = 0x%08x\n", res); asm volatile ("lcall %2, %3" : "=a" (res), "=c" (res2) : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc"); printf("func2() = 0x%08x spdec=%d\n", res, res2); asm volatile ("lcall %1, %2" : "=a" (res) : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc"); printf("func3() = 0x%08x\n", res);}#endif#if defined(__x86_64__)asm(".globl func_lret\n" "func_lret:\n" "movl $0x87654641, %eax\n" "lretq\n");#elseasm(".globl func_lret\n" "func_lret:\n" "movl $0x87654321, %eax\n" "lret\n" ".globl func_iret\n" "func_iret:\n" "movl $0xabcd4321, %eax\n" "iret\n");#endifextern char func_lret;extern char func_iret;void test_misc(void){ char table[256]; long res, i; for(i=0;i<256;i++) table[i] = 256 - i; res = 0x12345678; asm ("xlat" : "=a" (res) : "b" (table), "0" (res)); printf("xlat: EAX=" FMTLX "\n", res);#if defined(__x86_64__) { static struct __attribute__((packed)) { uint32_t offset; uint16_t seg; } desc; long cs_sel; asm volatile ("mov %%cs, %0" : "=r" (cs_sel)); asm volatile ("push %1\n" "call func_lret\n" : "=a" (res) : "r" (cs_sel) : "memory", "cc"); printf("func_lret=" FMTLX "\n", res); /* NOTE: we assume that &func_lret < 4GB */ desc.offset = (long)&func_lret; desc.seg = cs_sel; asm volatile ("xor %%rax, %%rax\n" "rex64 lcall %1\n" : "=a" (res) : "m" (desc) : "memory", "cc"); printf("func_lret2=" FMTLX "\n", res); asm volatile ("push %2\n" "mov $ 1f, %%rax\n" "push %%rax\n" "ljmp %1\n" "1:\n" : "=a" (res) : "m" (desc), "b" (cs_sel) : "memory", "cc"); printf("func_lret3=" FMTLX "\n", res); }#else asm volatile ("push %%cs ; call %1" : "=a" (res) : "m" (func_lret): "memory", "cc"); printf("func_lret=" FMTLX "\n", res); asm volatile ("pushf ; push %%cs ; call %1" : "=a" (res) : "m" (func_iret): "memory", "cc"); printf("func_iret=" FMTLX "\n", res);#endif#if defined(__x86_64__) /* specific popl test */ asm volatile ("push $12345432 ; push $0x9abcdef ; pop (%%rsp) ; pop %0" : "=g" (res)); printf("popl esp=" FMTLX "\n", res);#else /* specific popl test */ asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popl (%%esp) ; popl %0" : "=g" (res)); printf("popl esp=" FMTLX "\n", res); /* specific popw test */ asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popw (%%esp) ; addl $2, %%esp ; popl %0" : "=g" (res)); printf("popw esp=" FMTLX "\n", res);#endif}uint8_t str_buffer[4096];#define TEST_STRING1(OP, size, DF, REP)\{\ long esi, edi, eax, ecx, eflags;\\ esi = (long)(str_buffer + sizeof(str_buffer) / 2);\ edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\ eax = i2l(0x12345678);\ ecx = 17;\\ asm volatile ("push $0\n\t"\ "popf\n\t"\ DF "\n\t"\ REP #OP size "\n\t"\ "cld\n\t"\ "pushf\n\t"\ "pop %4\n\t"\ : "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\ : "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\ printf("%-10s ESI=" FMTLX " EDI=" FMTLX " EAX=" FMTLX " ECX=" FMTLX " EFL=%04x\n",\ REP #OP size, esi, edi, eax, ecx,\ (int)(eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)));\}#define TEST_STRING(OP, REP)\ TEST_STRING1(OP, "b", "", REP);\ TEST_STRING1(OP, "w", "", REP);\ TEST_STRING1(OP, "l", "", REP);\ X86_64_ONLY(TEST_STRING1(OP, "q", "", REP));\ TEST_STRING1(OP, "b", "std", REP);\ TEST_STRING1(OP, "w", "std", REP);\ TEST_STRING1(OP, "l", "std", REP);\ X86_64_ONLY(TEST_STRING1(OP, "q", "std", REP))void test_string(void){ int i; for(i = 0;i < sizeof(str_buffer); i++) str_buffer[i] = i + 0x56; TEST_STRING(stos, ""); TEST_STRING(stos, "rep "); TEST_STRING(lods, ""); /* to verify stos */ TEST_STRING(lods, "rep "); TEST_STRING(movs, ""); TEST_STRING(movs, "rep "); TEST_STRING(lods, ""); /* to verify stos */ /* XXX: better tests */ TEST_STRING(scas, ""); TEST_STRING(scas, "repz "); TEST_STRING(scas, "repnz "); TEST_STRING(cmps, ""); TEST_STRING(cmps, "repz "); TEST_STRING(cmps, "repnz ");}#ifdef TEST_VM86/* VM86 test */static inline void set_bit(uint8_t *a, unsigned int bit){ a[bit / 8] |= (1 << (bit % 8));}static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg){ return (uint8_t *)((seg << 4) + (reg & 0xffff));}static inline void pushw(struct vm86_regs *r, int val)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -