1 asm(".code16gcc"); 2 3 typedef unsigned char u8; 4 typedef unsigned short u16; 5 typedef unsigned u32; 6 typedef unsigned long long u64; 7 8 void test_function(void); 9 10 asm( 11 "test_function: \n\t" 12 "mov $0x1234, %eax \n\t" 13 "ret" 14 ); 15 16 static int strlen(const char *str) 17 { 18 int n; 19 20 for (n = 0; *str; ++str) 21 ++n; 22 return n; 23 } 24 25 static void print_serial(const char *buf) 26 { 27 unsigned long len = strlen(buf); 28 29 asm volatile ("cld; addr32/rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1)); 30 } 31 32 static void exit(int code) 33 { 34 asm volatile("out %0, %1" : : "a"(code), "d"((short)0xf4)); 35 } 36 37 struct regs { 38 u32 eax, ebx, ecx, edx; 39 u32 esi, edi, esp, ebp; 40 u32 eip, eflags; 41 }; 42 43 static u64 gdt[] = { 44 0, 45 0x00cf9b000000ffffull, // flat 32-bit code segment 46 0x00cf93000000ffffull, // flat 32-bit data segment 47 }; 48 49 static struct { 50 u16 limit; 51 void *base; 52 } __attribute__((packed)) gdt_descr = { 53 sizeof(gdt) - 1, 54 gdt, 55 }; 56 57 static void exec_in_big_real_mode(const struct regs *inregs, 58 struct regs *outregs, 59 const u8 *insn, int insn_len) 60 { 61 unsigned long tmp; 62 static struct regs save; 63 int i; 64 extern u8 test_insn[], test_insn_end[]; 65 66 for (i = 0; i < insn_len; ++i) 67 test_insn[i] = insn[i]; 68 for (; i < test_insn_end - test_insn; ++i) 69 test_insn[i] = 0x90; // nop 70 71 save = *inregs; 72 asm volatile( 73 "lgdtl %[gdt_descr] \n\t" 74 "mov %%cr0, %[tmp] \n\t" 75 "or $1, %[tmp] \n\t" 76 "mov %[tmp], %%cr0 \n\t" 77 "mov %[bigseg], %%gs \n\t" 78 "and $-2, %[tmp] \n\t" 79 "mov %[tmp], %%cr0 \n\t" 80 81 "pushw %[save]+36; popfw \n\t" 82 "xchg %%eax, %[save]+0 \n\t" 83 "xchg %%ebx, %[save]+4 \n\t" 84 "xchg %%ecx, %[save]+8 \n\t" 85 "xchg %%edx, %[save]+12 \n\t" 86 "xchg %%esi, %[save]+16 \n\t" 87 "xchg %%edi, %[save]+20 \n\t" 88 "xchg %%esp, %[save]+24 \n\t" 89 "xchg %%ebp, %[save]+28 \n\t" 90 91 "test_insn: . = . + 32\n\t" 92 "test_insn_end: \n\t" 93 94 "xchg %%eax, %[save]+0 \n\t" 95 "xchg %%ebx, %[save]+4 \n\t" 96 "xchg %%ecx, %[save]+8 \n\t" 97 "xchg %%edx, %[save]+12 \n\t" 98 "xchg %%esi, %[save]+16 \n\t" 99 "xchg %%edi, %[save]+20 \n\t" 100 "xchg %%esp, %[save]+24 \n\t" 101 "xchg %%ebp, %[save]+28 \n\t" 102 103 /* Save EFLAGS in outregs*/ 104 "pushfl \n\t" 105 "popl %[save]+36 \n\t" 106 107 "xor %[tmp], %[tmp] \n\t" 108 "mov %[tmp], %%gs \n\t" 109 : [tmp]"=&r"(tmp), [save]"+m"(save) 110 : [gdt_descr]"m"(gdt_descr), [bigseg]"r"((short)16) 111 : "cc", "memory" 112 ); 113 *outregs = save; 114 } 115 116 #define R_AX 1 117 #define R_BX 2 118 #define R_CX 4 119 #define R_DX 8 120 #define R_SI 16 121 #define R_DI 32 122 #define R_SP 64 123 #define R_BP 128 124 125 int regs_equal(const struct regs *r1, const struct regs *r2, int ignore) 126 { 127 const u32 *p1 = &r1->eax, *p2 = &r2->eax; // yuck 128 int i; 129 130 for (i = 0; i < 8; ++i) 131 if (!(ignore & (1 << i)) && p1[i] != p2[i]) 132 return 0; 133 return 1; 134 } 135 136 #define MK_INSN(name, str) \ 137 asm ( \ 138 ".text 1\n\t" \ 139 "insn_" #name ": " str " \n\t" \ 140 "insn_" #name "_end: \n\t" \ 141 ".text\n\t" \ 142 ); \ 143 extern u8 insn_##name[], insn_##name##_end[] 144 145 void test_xchg(void) 146 { 147 struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = 7}, outregs; 148 149 MK_INSN(xchg_test1, "xchg %eax,%eax\n\t"); 150 MK_INSN(xchg_test2, "xchg %eax,%ebx\n\t"); 151 MK_INSN(xchg_test3, "xchg %eax,%ecx\n\t"); 152 MK_INSN(xchg_test4, "xchg %eax,%edx\n\t"); 153 MK_INSN(xchg_test5, "xchg %eax,%esi\n\t"); 154 MK_INSN(xchg_test6, "xchg %eax,%edi\n\t"); 155 MK_INSN(xchg_test7, "xchg %eax,%ebp\n\t"); 156 MK_INSN(xchg_test8, "xchg %eax,%esp\n\t"); 157 158 exec_in_big_real_mode(&inregs, &outregs, 159 insn_xchg_test1, 160 insn_xchg_test1_end - insn_xchg_test1); 161 162 if (!regs_equal(&inregs, &outregs, 0)) 163 print_serial("xchg test 1: FAIL\n"); 164 else 165 print_serial("xchg test 1: PASS\n"); 166 167 exec_in_big_real_mode(&inregs, &outregs, 168 insn_xchg_test2, 169 insn_xchg_test2_end - insn_xchg_test2); 170 171 if (!regs_equal(&inregs, &outregs, R_AX | R_BX) || 172 outregs.eax != inregs.ebx || 173 outregs.ebx != inregs.eax) 174 print_serial("xchg test 2: FAIL\n"); 175 else 176 print_serial("xchg test 2: PASS\n"); 177 178 exec_in_big_real_mode(&inregs, &outregs, 179 insn_xchg_test3, 180 insn_xchg_test3_end - insn_xchg_test3); 181 182 if (!regs_equal(&inregs, &outregs, R_AX | R_CX) || 183 outregs.eax != inregs.ecx || 184 outregs.ecx != inregs.eax) 185 print_serial("xchg test 3: FAIL\n"); 186 else 187 print_serial("xchg test 3: PASS\n"); 188 189 exec_in_big_real_mode(&inregs, &outregs, 190 insn_xchg_test4, 191 insn_xchg_test4_end - insn_xchg_test4); 192 193 if (!regs_equal(&inregs, &outregs, R_AX | R_DX) || 194 outregs.eax != inregs.edx || 195 outregs.edx != inregs.eax) 196 print_serial("xchg test 4: FAIL\n"); 197 else 198 print_serial("xchg test 4: PASS\n"); 199 200 exec_in_big_real_mode(&inregs, &outregs, 201 insn_xchg_test5, 202 insn_xchg_test5_end - insn_xchg_test5); 203 204 if (!regs_equal(&inregs, &outregs, R_AX | R_SI) || 205 outregs.eax != inregs.esi || 206 outregs.esi != inregs.eax) 207 print_serial("xchg test 5: FAIL\n"); 208 else 209 print_serial("xchg test 5: PASS\n"); 210 211 exec_in_big_real_mode(&inregs, &outregs, 212 insn_xchg_test6, 213 insn_xchg_test6_end - insn_xchg_test6); 214 215 if (!regs_equal(&inregs, &outregs, R_AX | R_DI) || 216 outregs.eax != inregs.edi || 217 outregs.edi != inregs.eax) 218 print_serial("xchg test 6: FAIL\n"); 219 else 220 print_serial("xchg test 6: PASS\n"); 221 222 exec_in_big_real_mode(&inregs, &outregs, 223 insn_xchg_test7, 224 insn_xchg_test7_end - insn_xchg_test7); 225 226 if (!regs_equal(&inregs, &outregs, R_AX | R_BP) || 227 outregs.eax != inregs.ebp || 228 outregs.ebp != inregs.eax) 229 print_serial("xchg test 7: FAIL\n"); 230 else 231 print_serial("xchg test 7: PASS\n"); 232 233 exec_in_big_real_mode(&inregs, &outregs, 234 insn_xchg_test8, 235 insn_xchg_test8_end - insn_xchg_test8); 236 237 if (!regs_equal(&inregs, &outregs, R_AX | R_SP) || 238 outregs.eax != inregs.esp || 239 outregs.esp != inregs.eax) 240 print_serial("xchg test 8: FAIL\n"); 241 else 242 print_serial("xchg test 8: PASS\n"); 243 } 244 245 void test_shld(void) 246 { 247 struct regs inregs = { .eax = 0xbe, .edx = 0xef000000 }, outregs; 248 MK_INSN(shld_test, "shld $8,%edx,%eax\n\t"); 249 250 exec_in_big_real_mode(&inregs, &outregs, 251 insn_shld_test, 252 insn_shld_test_end - insn_shld_test); 253 if (outregs.eax != 0xbeef) 254 print_serial("shld: FAIL\n"); 255 else 256 print_serial("shld: PASS\n"); 257 } 258 259 void test_mov_imm(void) 260 { 261 struct regs inregs = { 0 }, outregs; 262 MK_INSN(mov_r32_imm_1, "mov $1234567890, %eax"); 263 MK_INSN(mov_r16_imm_1, "mov $1234, %ax"); 264 MK_INSN(mov_r8_imm_1, "mov $0x12, %ah"); 265 MK_INSN(mov_r8_imm_2, "mov $0x34, %al"); 266 MK_INSN(mov_r8_imm_3, "mov $0x12, %ah\n\t" "mov $0x34, %al\n\t"); 267 268 exec_in_big_real_mode(&inregs, &outregs, 269 insn_mov_r16_imm_1, 270 insn_mov_r16_imm_1_end - insn_mov_r16_imm_1); 271 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234) 272 print_serial("mov test 1: FAIL\n"); 273 else 274 print_serial("mov test 1: PASS\n"); 275 276 /* test mov $imm, %eax */ 277 exec_in_big_real_mode(&inregs, &outregs, 278 insn_mov_r32_imm_1, 279 insn_mov_r32_imm_1_end - insn_mov_r32_imm_1); 280 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234567890) 281 print_serial("mov test 2: FAIL\n"); 282 else 283 print_serial("mov test 2: PASS\n"); 284 285 /* test mov $imm, %al/%ah */ 286 exec_in_big_real_mode(&inregs, &outregs, 287 insn_mov_r8_imm_1, 288 insn_mov_r8_imm_1_end - insn_mov_r8_imm_1); 289 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1200) 290 print_serial("mov test 3: FAIL\n"); 291 else 292 print_serial("mov test 3: PASS\n"); 293 294 exec_in_big_real_mode(&inregs, &outregs, 295 insn_mov_r8_imm_2, 296 insn_mov_r8_imm_2_end - insn_mov_r8_imm_2); 297 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x34) 298 print_serial("mov test 4: FAIL\n"); 299 else 300 print_serial("mov test 4: PASS\n"); 301 302 exec_in_big_real_mode(&inregs, &outregs, 303 insn_mov_r8_imm_3, 304 insn_mov_r8_imm_3_end - insn_mov_r8_imm_3); 305 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 306 print_serial("mov test 5: FAIL\n"); 307 else 308 print_serial("mov test 5: PASS\n"); 309 } 310 311 void test_sub_imm(void) 312 { 313 struct regs inregs = { 0 }, outregs; 314 MK_INSN(sub_r32_imm_1, "mov $1234567890, %eax\n\t" "sub $10, %eax\n\t"); 315 MK_INSN(sub_r16_imm_1, "mov $1234, %ax\n\t" "sub $10, %ax\n\t"); 316 MK_INSN(sub_r8_imm_1, "mov $0x12, %ah\n\t" "sub $0x10, %ah\n\t"); 317 MK_INSN(sub_r8_imm_2, "mov $0x34, %al\n\t" "sub $0x10, %al\n\t"); 318 319 exec_in_big_real_mode(&inregs, &outregs, 320 insn_sub_r16_imm_1, 321 insn_sub_r16_imm_1_end - insn_sub_r16_imm_1); 322 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1224) 323 print_serial("sub test 1: FAIL\n"); 324 else 325 print_serial("sub test 1: PASS\n"); 326 327 /* test mov $imm, %eax */ 328 exec_in_big_real_mode(&inregs, &outregs, 329 insn_sub_r32_imm_1, 330 insn_sub_r32_imm_1_end - insn_sub_r32_imm_1); 331 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234567880) 332 print_serial("sub test 2: FAIL\n"); 333 else 334 print_serial("sub test 2: PASS\n"); 335 336 /* test mov $imm, %al/%ah */ 337 exec_in_big_real_mode(&inregs, &outregs, 338 insn_sub_r8_imm_1, 339 insn_sub_r8_imm_1_end - insn_sub_r8_imm_1); 340 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x0200) 341 print_serial("sub test 3: FAIL\n"); 342 else 343 print_serial("sub test 3: PASS\n"); 344 345 exec_in_big_real_mode(&inregs, &outregs, 346 insn_sub_r8_imm_2, 347 insn_sub_r8_imm_2_end - insn_sub_r8_imm_2); 348 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x24) 349 print_serial("sub test 4: FAIL\n"); 350 else 351 print_serial("sub test 4: PASS\n"); 352 } 353 354 355 void test_xor_imm(void) 356 { 357 struct regs inregs = { 0 }, outregs; 358 MK_INSN(xor_r32_imm_1, "mov $1234567890, %eax\n\t" "xor $1234567890, %eax\n\t"); 359 MK_INSN(xor_r16_imm_1, "mov $1234, %ax\n\t" "xor $1234, %ax\n\t"); 360 MK_INSN(xor_r8_imm_1, "mov $0x12, %ah\n\t" "xor $0x12, %ah\n\t"); 361 MK_INSN(xor_r8_imm_2, "mov $0x34, %al\n\t" "xor $0x34, %al\n\t"); 362 363 exec_in_big_real_mode(&inregs, &outregs, 364 insn_xor_r16_imm_1, 365 insn_xor_r16_imm_1_end - insn_xor_r16_imm_1); 366 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) 367 print_serial("xor test 1: FAIL\n"); 368 else 369 print_serial("xor test 1: PASS\n"); 370 371 /* test mov $imm, %eax */ 372 exec_in_big_real_mode(&inregs, &outregs, 373 insn_xor_r32_imm_1, 374 insn_xor_r32_imm_1_end - insn_xor_r32_imm_1); 375 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) 376 print_serial("xor test 2: FAIL\n"); 377 else 378 print_serial("xor test 2: PASS\n"); 379 380 /* test mov $imm, %al/%ah */ 381 exec_in_big_real_mode(&inregs, &outregs, 382 insn_xor_r8_imm_1, 383 insn_xor_r8_imm_1_end - insn_xor_r8_imm_1); 384 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) 385 print_serial("xor test 3: FAIL\n"); 386 else 387 print_serial("xor test 3: PASS\n"); 388 389 exec_in_big_real_mode(&inregs, &outregs, 390 insn_xor_r8_imm_2, 391 insn_xor_r8_imm_2_end - insn_xor_r8_imm_2); 392 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) 393 print_serial("xor test 4: FAIL\n"); 394 else 395 print_serial("xor test 4: PASS\n"); 396 } 397 398 void test_cmp_imm(void) 399 { 400 struct regs inregs = { 0 }, outregs; 401 MK_INSN(cmp_test1, "mov $0x34, %al\n\t" 402 "cmp $0x34, %al\n\t"); 403 MK_INSN(cmp_test2, "mov $0x34, %al\n\t" 404 "cmp $0x39, %al\n\t"); 405 MK_INSN(cmp_test3, "mov $0x34, %al\n\t" 406 "cmp $0x24, %al\n\t"); 407 408 /* test cmp imm8 with AL */ 409 /* ZF: (bit 6) Zero Flag becomes 1 if an operation results 410 * in a 0 writeback, or 0 register 411 */ 412 exec_in_big_real_mode(&inregs, &outregs, 413 insn_cmp_test1, 414 insn_cmp_test1_end - insn_cmp_test1); 415 if ((outregs.eflags & (1<<6)) != (1<<6)) 416 print_serial("cmp test 1: FAIL\n"); 417 else 418 print_serial("cmp test 1: PASS\n"); 419 420 exec_in_big_real_mode(&inregs, &outregs, 421 insn_cmp_test2, 422 insn_cmp_test2_end - insn_cmp_test2); 423 if ((outregs.eflags & (1<<6)) != 0) 424 print_serial("cmp test 2: FAIL\n"); 425 else 426 print_serial("cmp test 2: PASS\n"); 427 428 exec_in_big_real_mode(&inregs, &outregs, 429 insn_cmp_test3, 430 insn_cmp_test3_end - insn_cmp_test3); 431 if ((outregs.eflags & (1<<6)) != 0) 432 print_serial("cmp test 3: FAIL\n"); 433 else 434 print_serial("cmp test 3: PASS\n"); 435 } 436 437 void test_add_imm(void) 438 { 439 struct regs inregs = { 0 }, outregs; 440 MK_INSN(add_test1, "mov $0x43211234, %eax \n\t" 441 "add $0x12344321, %eax \n\t"); 442 MK_INSN(add_test2, "mov $0x12, %eax \n\t" 443 "add $0x21, %al\n\t"); 444 445 exec_in_big_real_mode(&inregs, &outregs, 446 insn_add_test1, 447 insn_add_test1_end - insn_add_test1); 448 if (outregs.eax != 0x55555555) 449 print_serial("add test 1: FAIL\n"); 450 else 451 print_serial("add test 1: PASS\n"); 452 453 exec_in_big_real_mode(&inregs, &outregs, 454 insn_add_test2, 455 insn_add_test2_end - insn_add_test2); 456 if (outregs.eax != 0x33) 457 print_serial("add test 2: FAIL\n"); 458 else 459 print_serial("add test 2: PASS\n"); 460 } 461 462 void test_eflags_insn(void) 463 { 464 struct regs inregs = { 0 }, outregs; 465 MK_INSN(clc, "clc"); 466 MK_INSN(stc, "stc"); 467 MK_INSN(cli, "cli"); 468 MK_INSN(sti, "sti"); 469 MK_INSN(cld, "cld"); 470 MK_INSN(std, "std"); 471 472 exec_in_big_real_mode(&inregs, &outregs, 473 insn_clc, 474 insn_clc_end - insn_clc); 475 if (outregs.eflags & 1) 476 print_serial("clc test: FAIL\n"); 477 else 478 print_serial("clc test: PASS\n"); 479 480 exec_in_big_real_mode(&inregs, &outregs, 481 insn_stc, 482 insn_stc_end - insn_stc); 483 if (!(outregs.eflags & 1)) 484 print_serial("stc test: FAIL\n"); 485 else 486 print_serial("stc test: PASS\n"); 487 488 exec_in_big_real_mode(&inregs, &outregs, 489 insn_cli, 490 insn_cli_end - insn_cli); 491 if (outregs.eflags & (1 << 9)) 492 print_serial("cli test: FAIL\n"); 493 else 494 print_serial("cli test: PASS\n"); 495 496 exec_in_big_real_mode(&inregs, &outregs, 497 insn_sti, 498 insn_sti_end - insn_sti); 499 if (!(outregs.eflags & (1 << 9))) 500 print_serial("sti test: FAIL\n"); 501 else 502 print_serial("sti test: PASS\n"); 503 504 exec_in_big_real_mode(&inregs, &outregs, 505 insn_cld, 506 insn_cld_end - insn_cld); 507 if (outregs.eflags & (1 << 10)) 508 print_serial("cld test: FAIL\n"); 509 else 510 print_serial("cld test: PASS\n"); 511 512 exec_in_big_real_mode(&inregs, &outregs, 513 insn_std, 514 insn_std_end - insn_std); 515 if (!(outregs.eflags & (1 << 10))) 516 print_serial("std test: FAIL\n"); 517 else 518 print_serial("std test: PASS\n"); 519 } 520 521 void test_io(void) 522 { 523 struct regs inregs = { 0 }, outregs; 524 MK_INSN(io_test1, "mov $0xff, %al \n\t" 525 "out %al, $0xe0 \n\t" 526 "mov $0x00, %al \n\t" 527 "in $0xe0, %al \n\t"); 528 MK_INSN(io_test2, "mov $0xffff, %ax \n\t" 529 "out %ax, $0xe0 \n\t" 530 "mov $0x0000, %ax \n\t" 531 "in $0xe0, %ax \n\t"); 532 MK_INSN(io_test3, "mov $0xffffffff, %eax \n\t" 533 "out %eax, $0xe0 \n\t" 534 "mov $0x000000, %eax \n\t" 535 "in $0xe0, %eax \n\t"); 536 MK_INSN(io_test4, "mov $0xe0, %dx \n\t" 537 "mov $0xff, %al \n\t" 538 "out %al, %dx \n\t" 539 "mov $0x00, %al \n\t" 540 "in %dx, %al \n\t"); 541 MK_INSN(io_test5, "mov $0xe0, %dx \n\t" 542 "mov $0xffff, %ax \n\t" 543 "out %ax, %dx \n\t" 544 "mov $0x0000, %ax \n\t" 545 "in %dx, %ax \n\t"); 546 MK_INSN(io_test6, "mov $0xe0, %dx \n\t" 547 "mov $0xffffffff, %eax \n\t" 548 "out %eax, %dx \n\t" 549 "mov $0x00000000, %eax \n\t" 550 "in %dx, %eax \n\t"); 551 552 exec_in_big_real_mode(&inregs, &outregs, 553 insn_io_test1, 554 insn_io_test1_end - insn_io_test1); 555 556 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xff) 557 print_serial("I/O test 1: FAIL\n"); 558 else 559 print_serial("I/O test 1: PASS\n"); 560 561 exec_in_big_real_mode(&inregs, &outregs, 562 insn_io_test2, 563 insn_io_test2_end - insn_io_test2); 564 565 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xffff) 566 print_serial("I/O test 2: FAIL\n"); 567 else 568 print_serial("I/O test 2: PASS\n"); 569 570 exec_in_big_real_mode(&inregs, &outregs, 571 insn_io_test3, 572 insn_io_test3_end - insn_io_test3); 573 574 if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xffffffff) 575 print_serial("I/O test 3: FAIL\n"); 576 else 577 print_serial("I/O test 3: PASS\n"); 578 579 exec_in_big_real_mode(&inregs, &outregs, 580 insn_io_test4, 581 insn_io_test4_end - insn_io_test4); 582 583 if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xff) 584 print_serial("I/O test 4: FAIL\n"); 585 else 586 print_serial("I/O test 4: PASS\n"); 587 588 exec_in_big_real_mode(&inregs, &outregs, 589 insn_io_test5, 590 insn_io_test5_end - insn_io_test5); 591 592 if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xffff) 593 print_serial("I/O test 5: FAIL\n"); 594 else 595 print_serial("I/O test 5: PASS\n"); 596 597 exec_in_big_real_mode(&inregs, &outregs, 598 insn_io_test6, 599 insn_io_test6_end - insn_io_test6); 600 601 if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xffffffff) 602 print_serial("I/O test 6: FAIL\n"); 603 else 604 print_serial("I/O test 6: PASS\n"); 605 } 606 607 void test_call(void) 608 { 609 struct regs inregs = { 0 }, outregs; 610 u32 esp[16]; 611 612 inregs.esp = (u32)esp; 613 614 MK_INSN(call1, "mov $test_function, %eax \n\t" 615 "call *%eax\n\t"); 616 MK_INSN(call_near1, "jmp 2f\n\t" 617 "1: mov $0x1234, %eax\n\t" 618 "ret\n\t" 619 "2: call 1b\t"); 620 MK_INSN(call_near2, "call 1f\n\t" 621 "jmp 2f\n\t" 622 "1: mov $0x1234, %eax\n\t" 623 "ret\n\t" 624 "2:\t"); 625 626 exec_in_big_real_mode(&inregs, &outregs, 627 insn_call1, 628 insn_call1_end - insn_call1); 629 if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 630 print_serial("Call Test 1: FAIL\n"); 631 else 632 print_serial("Call Test 1: PASS\n"); 633 634 exec_in_big_real_mode(&inregs, &outregs, 635 insn_call_near1, insn_call_near1_end - insn_call_near1); 636 if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 637 print_serial("Call near Test 1: FAIL\n"); 638 else 639 print_serial("Call near Test 1: PASS\n"); 640 641 exec_in_big_real_mode(&inregs, &outregs, 642 insn_call_near2, insn_call_near2_end - insn_call_near2); 643 if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 644 print_serial("Call near Test 2: FAIL\n"); 645 else 646 print_serial("Call near Test 2: PASS\n"); 647 } 648 649 void test_jcc_short(void) 650 { 651 struct regs inregs = { 0 }, outregs; 652 MK_INSN(jnz_short1, "jnz 1f\n\t" 653 "mov $0x1234, %eax\n\t" 654 "1:\n\t"); 655 MK_INSN(jnz_short2, "1:\n\t" 656 "cmp $0x1234, %eax\n\t" 657 "mov $0x1234, %eax\n\t" 658 "jnz 1b\n\t"); 659 MK_INSN(jmp_short1, "jmp 1f\n\t" 660 "mov $0x1234, %eax\n\t" 661 "1:\n\t"); 662 663 exec_in_big_real_mode(&inregs, &outregs, 664 insn_jnz_short1, insn_jnz_short1_end - insn_jnz_short1); 665 if(!regs_equal(&inregs, &outregs, 0)) 666 print_serial("JNZ short Test 1: FAIL\n"); 667 else 668 print_serial("JNZ short Test 1: PASS\n"); 669 670 exec_in_big_real_mode(&inregs, &outregs, 671 insn_jnz_short2, insn_jnz_short2_end - insn_jnz_short2); 672 if(!regs_equal(&inregs, &outregs, R_AX) || !(outregs.eflags & (1 << 6))) 673 print_serial("JNZ short Test 2: FAIL\n"); 674 else 675 print_serial("JNZ short Test 2: PASS\n"); 676 677 exec_in_big_real_mode(&inregs, &outregs, 678 insn_jmp_short1, insn_jmp_short1_end - insn_jmp_short1); 679 if(!regs_equal(&inregs, &outregs, 0)) 680 print_serial("JMP short Test 1: FAIL\n"); 681 else 682 print_serial("JMP short Test 1: PASS\n"); 683 } 684 685 void test_jcc_near(void) 686 { 687 struct regs inregs = { 0 }, outregs; 688 /* encode near jmp manually. gas will not do it if offsets < 127 byte */ 689 MK_INSN(jnz_near1, ".byte 0x0f, 0x85, 0x06, 0x00\n\t" 690 "mov $0x1234, %eax\n\t"); 691 MK_INSN(jnz_near2, "cmp $0x1234, %eax\n\t" 692 "mov $0x1234, %eax\n\t" 693 ".byte 0x0f, 0x85, 0xf0, 0xff\n\t"); 694 MK_INSN(jmp_near1, ".byte 0xE9, 0x06, 0x00\n\t" 695 "mov $0x1234, %eax\n\t"); 696 697 exec_in_big_real_mode(&inregs, &outregs, 698 insn_jnz_near1, insn_jnz_near1_end - insn_jnz_near1); 699 if(!regs_equal(&inregs, &outregs, 0)) 700 print_serial("JNZ near Test 1: FAIL\n"); 701 else 702 print_serial("JNZ near Test 1: PASS\n"); 703 704 exec_in_big_real_mode(&inregs, &outregs, 705 insn_jnz_near2, insn_jnz_near2_end - insn_jnz_near2); 706 if(!regs_equal(&inregs, &outregs, R_AX) || !(outregs.eflags & (1 << 6))) 707 print_serial("JNZ near Test 2: FAIL\n"); 708 else 709 print_serial("JNZ near Test 2: PASS\n"); 710 711 exec_in_big_real_mode(&inregs, &outregs, 712 insn_jmp_near1, insn_jmp_near1_end - insn_jmp_near1); 713 if(!regs_equal(&inregs, &outregs, 0)) 714 print_serial("JMP near Test 1: FAIL\n"); 715 else 716 print_serial("JMP near Test 1: PASS\n"); 717 } 718 719 void test_long_jmp() 720 { 721 struct regs inregs = { 0 }, outregs; 722 u32 esp[16]; 723 724 inregs.esp = (u32)esp; 725 MK_INSN(long_jmp, "call 1f\n\t" 726 "jmp 2f\n\t" 727 "1: jmp $0, $test_function\n\t" 728 "2:\n\t"); 729 exec_in_big_real_mode(&inregs, &outregs, 730 insn_long_jmp, 731 insn_long_jmp_end - insn_long_jmp); 732 if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 733 print_serial("Long JMP Test: FAIL\n"); 734 else 735 print_serial("Long JMP Test: PASS\n"); 736 } 737 738 void test_push_pop() 739 { 740 struct regs inregs = { 0 }, outregs; 741 MK_INSN(push32, "mov $0x12345678, %eax\n\t" 742 "push %eax\n\t" 743 "pop %ebx\n\t"); 744 MK_INSN(push16, "mov $0x1234, %ax\n\t" 745 "push %ax\n\t" 746 "pop %bx\n\t"); 747 748 MK_INSN(push_es, "mov $0x231, %bx\n\t" //Just write a dummy value to see if it gets overwritten 749 "mov $0x123, %ax\n\t" 750 "mov %ax, %es\n\t" 751 "push %es\n\t" 752 "pop %bx \n\t" 753 ); 754 MK_INSN(pop_es, "push %ax\n\t" 755 "pop %es\n\t" 756 "mov %es, %bx\n\t" 757 ); 758 MK_INSN(push_pop_ss, "push %ss\n\t" 759 "pushw %ax\n\t" 760 "popw %ss\n\t" 761 "mov %ss, %bx\n\t" 762 "pop %ss\n\t" 763 ); 764 MK_INSN(push_pop_fs, "push %fs\n\t" 765 "pushl %eax\n\t" 766 "popl %fs\n\t" 767 "mov %fs, %ebx\n\t" 768 "pop %fs\n\t" 769 ); 770 771 exec_in_big_real_mode(&inregs, &outregs, 772 insn_push32, 773 insn_push32_end - insn_push32); 774 if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.eax != outregs.ebx || outregs.eax != 0x12345678) 775 print_serial("Push/Pop Test 1: FAIL\n"); 776 else 777 print_serial("Push/Pop Test 1: PASS\n"); 778 779 exec_in_big_real_mode(&inregs, &outregs, 780 insn_push16, 781 insn_push16_end - insn_push16); 782 783 if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.eax != outregs.ebx || outregs.eax != 0x1234) 784 print_serial("Push/Pop Test 2: FAIL\n"); 785 else 786 print_serial("Push/Pop Test 2: PASS\n"); 787 788 exec_in_big_real_mode(&inregs, &outregs, 789 insn_push_es, 790 insn_push_es_end - insn_push_es); 791 if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax || outregs.eax != 0x123) 792 print_serial("Push/Pop Test 3: FAIL\n"); 793 else 794 print_serial("Push/Pop Test 3: PASS\n"); 795 796 exec_in_big_real_mode(&inregs, &outregs, 797 insn_pop_es, 798 insn_pop_es_end - insn_pop_es); 799 800 if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax) 801 print_serial("Push/Pop Test 4: FAIL\n"); 802 else 803 print_serial("Push/Pop Test 4: PASS\n"); 804 805 exec_in_big_real_mode(&inregs, &outregs, 806 insn_push_pop_ss, 807 insn_push_pop_ss_end - insn_push_pop_ss); 808 809 if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax) 810 print_serial("Push/Pop Test 5: FAIL\n"); 811 else 812 print_serial("Push/Pop Test 5: PASS\n"); 813 814 exec_in_big_real_mode(&inregs, &outregs, 815 insn_push_pop_fs, 816 insn_push_pop_fs_end - insn_push_pop_fs); 817 818 if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax) 819 print_serial("Push/Pop Test 6: FAIL\n"); 820 else 821 print_serial("Push/Pop Test 6: PASS\n"); 822 } 823 824 void test_null(void) 825 { 826 struct regs inregs = { 0 }, outregs; 827 exec_in_big_real_mode(&inregs, &outregs, 0, 0); 828 if (!regs_equal(&inregs, &outregs, 0)) 829 print_serial("null test: FAIL\n"); 830 else 831 print_serial("null test: PASS\n"); 832 } 833 834 struct { 835 char stack[500]; 836 char top[]; 837 } tmp_stack; 838 839 void test_pusha_popa() 840 { 841 struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = (unsigned long)&tmp_stack.top }, outregs; 842 843 MK_INSN(pusha, "pusha\n\t" 844 "pop %edi\n\t" 845 "pop %esi\n\t" 846 "pop %ebp\n\t" 847 "add $4, %esp\n\t" 848 "pop %ebx\n\t" 849 "pop %edx\n\t" 850 "pop %ecx\n\t" 851 "pop %eax\n\t" 852 ); 853 854 MK_INSN(popa, "push %eax\n\t" 855 "push %ecx\n\t" 856 "push %edx\n\t" 857 "push %ebx\n\t" 858 "push %esp\n\t" 859 "push %ebp\n\t" 860 "push %esi\n\t" 861 "push %edi\n\t" 862 "popa\n\t" 863 ); 864 865 exec_in_big_real_mode(&inregs, &outregs, 866 insn_pusha, 867 insn_pusha_end - insn_pusha); 868 869 if (!regs_equal(&inregs, &outregs, 0)) 870 print_serial("Pusha/Popa Test1: FAIL\n"); 871 else 872 print_serial("Pusha/Popa Test1: PASS\n"); 873 874 exec_in_big_real_mode(&inregs, &outregs, 875 insn_popa, 876 insn_popa_end - insn_popa); 877 if (!regs_equal(&inregs, &outregs, 0)) 878 print_serial("Pusha/Popa Test2: FAIL\n"); 879 else 880 print_serial("Pusha/Popa Test2: PASS\n"); 881 } 882 883 void test_iret() 884 { 885 struct regs inregs = { 0 }, outregs; 886 887 MK_INSN(iret32, "pushf\n\t" 888 "pushl %cs\n\t" 889 "call 1f\n\t" /* a near call will push eip onto the stack */ 890 "jmp 2f\n\t" 891 "1: iret\n\t" 892 "2:\n\t" 893 ); 894 895 MK_INSN(iret16, "pushfw\n\t" 896 "pushw %cs\n\t" 897 "callw 1f\n\t" 898 "jmp 2f\n\t" 899 "1: iretw\n\t" 900 "2:\n\t"); 901 902 MK_INSN(iret_flags32, "pushfl\n\t" 903 "popl %eax\n\t" 904 "andl $~0x2, %eax\n\t" 905 "orl $0xffc08028, %eax\n\t" 906 "pushl %eax\n\t" 907 "pushl %cs\n\t" 908 "call 1f\n\t" 909 "jmp 2f\n\t" 910 "1: iret\n\t" 911 "2:\n\t"); 912 913 MK_INSN(iret_flags16, "pushfw\n\t" 914 "popw %ax\n\t" 915 "and $~0x2, %ax\n\t" 916 "or $0x8028, %ax\n\t" 917 "pushw %ax\n\t" 918 "pushw %cs\n\t" 919 "callw 1f\n\t" 920 "jmp 2f\n\t" 921 "1: iretw\n\t" 922 "2:\n\t"); 923 924 exec_in_big_real_mode(&inregs, &outregs, 925 insn_iret32, 926 insn_iret32_end - insn_iret32); 927 928 if (!regs_equal(&inregs, &outregs, 0)) 929 print_serial("iret Test 1: FAIL\n"); 930 else 931 print_serial("iret Test 1: PASS\n"); 932 933 exec_in_big_real_mode(&inregs, &outregs, 934 insn_iret16, 935 insn_iret16_end - insn_iret16); 936 937 if (!regs_equal(&inregs, &outregs, 0)) 938 print_serial("iret Test 2: FAIL\n"); 939 else 940 print_serial("iret Test 2: PASS\n"); 941 942 exec_in_big_real_mode(&inregs, &outregs, 943 insn_iret_flags32, 944 insn_iret_flags32_end - insn_iret_flags32); 945 946 if (!regs_equal(&inregs, &outregs, R_AX)) 947 print_serial("iret Test 3: FAIL\n"); 948 else 949 print_serial("iret Test 3: PASS\n"); 950 951 exec_in_big_real_mode(&inregs, &outregs, 952 insn_iret_flags16, 953 insn_iret_flags16_end - insn_iret_flags16); 954 955 if (!regs_equal(&inregs, &outregs, R_AX)) 956 print_serial("iret Test 4: FAIL\n"); 957 else 958 print_serial("iret Test 4: PASS\n"); 959 } 960 961 void test_int() 962 { 963 struct regs inregs = { 0 }, outregs; 964 965 *(u32 *)(0x11 * 4) = 0x1000; /* Store a pointer to address 0x1000 in IDT entry 0x11 */ 966 *(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */ 967 968 MK_INSN(int11, "int $0x11\n\t"); 969 970 exec_in_big_real_mode(&inregs, &outregs, 971 insn_int11, 972 insn_int11_end - insn_int11); 973 974 if (!regs_equal(&inregs, &outregs, 0)) 975 print_serial("int Test 1: FAIL\n"); 976 else 977 print_serial("int Test 1: PASS\n"); 978 } 979 980 void test_imul() 981 { 982 struct regs inregs = { 0 }, outregs; 983 984 MK_INSN(imul8_1, "mov $2, %al\n\t" 985 "mov $-4, %cx\n\t" 986 "imul %cl\n\t"); 987 988 MK_INSN(imul16_1, "mov $2, %ax\n\t" 989 "mov $-4, %cx\n\t" 990 "imul %cx\n\t"); 991 992 MK_INSN(imul32_1, "mov $2, %eax\n\t" 993 "mov $-4, %ecx\n\t" 994 "imul %ecx\n\t"); 995 996 MK_INSN(imul8_2, "mov $0x12340002, %eax\n\t" 997 "mov $4, %cx\n\t" 998 "imul %cl\n\t"); 999 1000 MK_INSN(imul16_2, "mov $2, %ax\n\t" 1001 "mov $4, %cx\n\t" 1002 "imul %cx\n\t"); 1003 1004 MK_INSN(imul32_2, "mov $2, %eax\n\t" 1005 "mov $4, %ecx\n\t" 1006 "imul %ecx\n\t"); 1007 1008 exec_in_big_real_mode(&inregs, &outregs, 1009 insn_imul8_1, 1010 insn_imul8_1_end - insn_imul8_1); 1011 1012 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xff) != (u8)-8) 1013 print_serial("imul Test 1: FAIL\n"); 1014 else 1015 print_serial("imul Test 1: PASS\n"); 1016 1017 exec_in_big_real_mode(&inregs, &outregs, 1018 insn_imul16_1, 1019 insn_imul16_1_end - insn_imul16_1); 1020 1021 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u16)-8) 1022 print_serial("imul Test 2: FAIL\n"); 1023 else 1024 print_serial("imul Test 2: PASS\n"); 1025 1026 exec_in_big_real_mode(&inregs, &outregs, 1027 insn_imul32_1, 1028 insn_imul32_1_end - insn_imul32_1); 1029 1030 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u32)-8) 1031 print_serial("imul Test 3: FAIL\n"); 1032 else 1033 print_serial("imul Test 3: PASS\n"); 1034 1035 exec_in_big_real_mode(&inregs, &outregs, 1036 insn_imul8_2, 1037 insn_imul8_2_end - insn_imul8_2); 1038 1039 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xffff) != 8 || 1040 (outregs.eax & 0xffff0000) != 0x12340000) 1041 print_serial("imul Test 4: FAIL\n"); 1042 else 1043 print_serial("imul Test 4: PASS\n"); 1044 1045 exec_in_big_real_mode(&inregs, &outregs, 1046 insn_imul16_2, 1047 insn_imul16_2_end - insn_imul16_2); 1048 1049 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8) 1050 print_serial("imul Test 5: FAIL\n"); 1051 else 1052 print_serial("imul Test 5: PASS\n"); 1053 1054 exec_in_big_real_mode(&inregs, &outregs, 1055 insn_imul32_2, 1056 insn_imul32_2_end - insn_imul32_2); 1057 1058 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8) 1059 print_serial("imul Test 6: FAIL\n"); 1060 else 1061 print_serial("imul Test 6: PASS\n"); 1062 } 1063 1064 void test_mul() 1065 { 1066 struct regs inregs = { 0 }, outregs; 1067 1068 MK_INSN(mul8, "mov $2, %al\n\t" 1069 "mov $4, %cx\n\t" 1070 "imul %cl\n\t"); 1071 1072 MK_INSN(mul16, "mov $2, %ax\n\t" 1073 "mov $4, %cx\n\t" 1074 "imul %cx\n\t"); 1075 1076 MK_INSN(mul32, "mov $2, %eax\n\t" 1077 "mov $4, %ecx\n\t" 1078 "imul %ecx\n\t"); 1079 1080 exec_in_big_real_mode(&inregs, &outregs, 1081 insn_mul8, 1082 insn_mul8_end - insn_mul8); 1083 1084 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xff) != 8) 1085 print_serial("mul Test 1: FAIL\n"); 1086 else 1087 print_serial("mul Test 1: PASS\n"); 1088 1089 exec_in_big_real_mode(&inregs, &outregs, 1090 insn_mul16, 1091 insn_mul16_end - insn_mul16); 1092 1093 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8) 1094 print_serial("mul Test 2: FAIL\n"); 1095 else 1096 print_serial("mul Test 2: PASS\n"); 1097 1098 exec_in_big_real_mode(&inregs, &outregs, 1099 insn_mul32, 1100 insn_mul32_end - insn_mul32); 1101 1102 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8) 1103 print_serial("mul Test 3: FAIL\n"); 1104 else 1105 print_serial("mul Test 3: PASS\n"); 1106 } 1107 1108 void test_div() 1109 { 1110 struct regs inregs = { 0 }, outregs; 1111 1112 MK_INSN(div8, "mov $257, %ax\n\t" 1113 "mov $2, %cl\n\t" 1114 "div %cl\n\t"); 1115 1116 MK_INSN(div16, "mov $512, %ax\n\t" 1117 "mov $5, %cx\n\t" 1118 "div %cx\n\t"); 1119 1120 MK_INSN(div32, "mov $512, %eax\n\t" 1121 "mov $5, %ecx\n\t" 1122 "div %ecx\n\t"); 1123 1124 exec_in_big_real_mode(&inregs, &outregs, 1125 insn_div8, 1126 insn_div8_end - insn_div8); 1127 1128 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 384) 1129 print_serial("div Test 1: FAIL\n"); 1130 else 1131 print_serial("div Test 1: PASS\n"); 1132 1133 exec_in_big_real_mode(&inregs, &outregs, 1134 insn_div16, 1135 insn_div16_end - insn_div16); 1136 1137 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 102 || 1138 outregs.edx != 2) 1139 print_serial("div Test 2: FAIL\n"); 1140 else 1141 print_serial("div Test 2: PASS\n"); 1142 1143 exec_in_big_real_mode(&inregs, &outregs, 1144 insn_div32, 1145 insn_div32_end - insn_div32); 1146 1147 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 102 || 1148 outregs.edx != 2) 1149 print_serial("div Test 3: FAIL\n"); 1150 else 1151 print_serial("div Test 3: PASS\n"); 1152 } 1153 1154 void test_idiv() 1155 { 1156 struct regs inregs = { 0 }, outregs; 1157 1158 MK_INSN(idiv8, "mov $256, %ax\n\t" 1159 "mov $-2, %cl\n\t" 1160 "idiv %cl\n\t"); 1161 1162 MK_INSN(idiv16, "mov $512, %ax\n\t" 1163 "mov $-2, %cx\n\t" 1164 "idiv %cx\n\t"); 1165 1166 MK_INSN(idiv32, "mov $512, %eax\n\t" 1167 "mov $-2, %ecx\n\t" 1168 "idiv %ecx\n\t"); 1169 1170 exec_in_big_real_mode(&inregs, &outregs, 1171 insn_idiv8, 1172 insn_idiv8_end - insn_idiv8); 1173 1174 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u8)-128) 1175 print_serial("idiv Test 1: FAIL\n"); 1176 else 1177 print_serial("idiv Test 1: PASS\n"); 1178 1179 exec_in_big_real_mode(&inregs, &outregs, 1180 insn_idiv16, 1181 insn_idiv16_end - insn_idiv16); 1182 1183 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u16)-256) 1184 print_serial("idiv Test 2: FAIL\n"); 1185 else 1186 print_serial("idiv Test 2: PASS\n"); 1187 1188 exec_in_big_real_mode(&inregs, &outregs, 1189 insn_idiv32, 1190 insn_idiv32_end - insn_idiv32); 1191 1192 if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u32)-256) 1193 print_serial("idiv Test 3: FAIL\n"); 1194 else 1195 print_serial("idiv Test 3: PASS\n"); 1196 } 1197 1198 void test_cbw(void) 1199 { 1200 struct regs inregs = { 0 }, outregs; 1201 1202 MK_INSN(cbw, "mov $0xFE, %eax \n\t" 1203 "cbw\n\t"); 1204 MK_INSN(cwde, "mov $0xFFFE, %eax \n\t" 1205 "cwde\n\t"); 1206 1207 exec_in_big_real_mode(&inregs, &outregs, 1208 insn_cbw, 1209 insn_cbw_end - insn_cbw); 1210 if (outregs.eax != 0xFFFE) 1211 print_serial("cbw test1: FAIL\n"); 1212 else 1213 print_serial("cbw test 1: PASS\n"); 1214 1215 exec_in_big_real_mode(&inregs, &outregs, 1216 insn_cwde, 1217 insn_cwde_end - insn_cwde); 1218 if (outregs.eax != 0xFFFFFFFE) 1219 print_serial("cwde test1: FAIL\n"); 1220 else 1221 print_serial("cwde test 1: PASS\n"); 1222 } 1223 1224 void test_loopcc(void) 1225 { 1226 struct regs inregs = { 0 }, outregs; 1227 1228 MK_INSN(loop, "mov $10, %ecx\n\t" 1229 "1: inc %eax\n\t" 1230 "loop 1b\n\t"); 1231 1232 MK_INSN(loope, "mov $10, %ecx\n\t" 1233 "mov $1, %eax\n\t" 1234 "1: dec %eax\n\t" 1235 "loope 1b\n\t"); 1236 1237 MK_INSN(loopne, "mov $10, %ecx\n\t" 1238 "mov $5, %eax\n\t" 1239 "1: dec %eax\n\t" 1240 "loopne 1b\n\t"); 1241 1242 exec_in_big_real_mode(&inregs, &outregs, 1243 insn_loop, insn_loop_end - insn_loop); 1244 if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 10) 1245 print_serial("LOOPcc short Test 1: FAIL\n"); 1246 else 1247 print_serial("LOOPcc short Test 1: PASS\n"); 1248 1249 exec_in_big_real_mode(&inregs, &outregs, 1250 insn_loope, insn_loope_end - insn_loope); 1251 if(!regs_equal(&inregs, &outregs, R_AX | R_CX) || 1252 outregs.eax != -1 || outregs.ecx != 8) 1253 print_serial("LOOPcc short Test 2: FAIL\n"); 1254 else 1255 print_serial("LOOPcc short Test 2: PASS\n"); 1256 1257 exec_in_big_real_mode(&inregs, &outregs, 1258 insn_loopne, insn_loopne_end - insn_loopne); 1259 if(!regs_equal(&inregs, &outregs, R_AX | R_CX) || 1260 outregs.eax != 0 || outregs.ecx != 5) 1261 print_serial("LOOPcc short Test 3: FAIL\n"); 1262 else 1263 print_serial("LOOPcc short Test 3: PASS\n"); 1264 } 1265 1266 static void test_das(void) 1267 { 1268 struct regs inregs = { 0 }, outregs = { 0 }; 1269 short i; 1270 static unsigned test_cases[1024] = { 1271 0x46000000, 0x8701a000, 0x9710fa00, 0x97119a00, 1272 0x02000101, 0x8301a101, 0x9310fb01, 0x93119b01, 1273 0x02000202, 0x8301a202, 0x9710fc02, 0x97119c02, 1274 0x06000303, 0x8701a303, 0x9310fd03, 0x93119d03, 1275 0x02000404, 0x8301a404, 0x9310fe04, 0x93119e04, 1276 0x06000505, 0x8701a505, 0x9710ff05, 0x97119f05, 1277 0x06000606, 0x8701a606, 0x56100006, 0x9711a006, 1278 0x02000707, 0x8301a707, 0x12100107, 0x9311a107, 1279 0x02000808, 0x8301a808, 0x12100208, 0x9311a208, 1280 0x06000909, 0x8701a909, 0x16100309, 0x9711a309, 1281 0x1200040a, 0x9301a40a, 0x1210040a, 0x9311a40a, 1282 0x1600050b, 0x9701a50b, 0x1610050b, 0x9711a50b, 1283 0x1600060c, 0x9701a60c, 0x1610060c, 0x9711a60c, 1284 0x1200070d, 0x9301a70d, 0x1210070d, 0x9311a70d, 1285 0x1200080e, 0x9301a80e, 0x1210080e, 0x9311a80e, 1286 0x1600090f, 0x9701a90f, 0x1610090f, 0x9711a90f, 1287 0x02001010, 0x8301b010, 0x16100a10, 0x9711aa10, 1288 0x06001111, 0x8701b111, 0x12100b11, 0x9311ab11, 1289 0x06001212, 0x8701b212, 0x16100c12, 0x9711ac12, 1290 0x02001313, 0x8301b313, 0x12100d13, 0x9311ad13, 1291 0x06001414, 0x8701b414, 0x12100e14, 0x9311ae14, 1292 0x02001515, 0x8301b515, 0x16100f15, 0x9711af15, 1293 0x02001616, 0x8301b616, 0x12101016, 0x9311b016, 1294 0x06001717, 0x8701b717, 0x16101117, 0x9711b117, 1295 0x06001818, 0x8701b818, 0x16101218, 0x9711b218, 1296 0x02001919, 0x8301b919, 0x12101319, 0x9311b319, 1297 0x1600141a, 0x9701b41a, 0x1610141a, 0x9711b41a, 1298 0x1200151b, 0x9301b51b, 0x1210151b, 0x9311b51b, 1299 0x1200161c, 0x9301b61c, 0x1210161c, 0x9311b61c, 1300 0x1600171d, 0x9701b71d, 0x1610171d, 0x9711b71d, 1301 0x1600181e, 0x9701b81e, 0x1610181e, 0x9711b81e, 1302 0x1200191f, 0x9301b91f, 0x1210191f, 0x9311b91f, 1303 0x02002020, 0x8701c020, 0x12101a20, 0x9311ba20, 1304 0x06002121, 0x8301c121, 0x16101b21, 0x9711bb21, 1305 0x06002222, 0x8301c222, 0x12101c22, 0x9311bc22, 1306 0x02002323, 0x8701c323, 0x16101d23, 0x9711bd23, 1307 0x06002424, 0x8301c424, 0x16101e24, 0x9711be24, 1308 0x02002525, 0x8701c525, 0x12101f25, 0x9311bf25, 1309 0x02002626, 0x8701c626, 0x12102026, 0x9711c026, 1310 0x06002727, 0x8301c727, 0x16102127, 0x9311c127, 1311 0x06002828, 0x8301c828, 0x16102228, 0x9311c228, 1312 0x02002929, 0x8701c929, 0x12102329, 0x9711c329, 1313 0x1600242a, 0x9301c42a, 0x1610242a, 0x9311c42a, 1314 0x1200252b, 0x9701c52b, 0x1210252b, 0x9711c52b, 1315 0x1200262c, 0x9701c62c, 0x1210262c, 0x9711c62c, 1316 0x1600272d, 0x9301c72d, 0x1610272d, 0x9311c72d, 1317 0x1600282e, 0x9301c82e, 0x1610282e, 0x9311c82e, 1318 0x1200292f, 0x9701c92f, 0x1210292f, 0x9711c92f, 1319 0x06003030, 0x8301d030, 0x12102a30, 0x9711ca30, 1320 0x02003131, 0x8701d131, 0x16102b31, 0x9311cb31, 1321 0x02003232, 0x8701d232, 0x12102c32, 0x9711cc32, 1322 0x06003333, 0x8301d333, 0x16102d33, 0x9311cd33, 1323 0x02003434, 0x8701d434, 0x16102e34, 0x9311ce34, 1324 0x06003535, 0x8301d535, 0x12102f35, 0x9711cf35, 1325 0x06003636, 0x8301d636, 0x16103036, 0x9311d036, 1326 0x02003737, 0x8701d737, 0x12103137, 0x9711d137, 1327 0x02003838, 0x8701d838, 0x12103238, 0x9711d238, 1328 0x06003939, 0x8301d939, 0x16103339, 0x9311d339, 1329 0x1200343a, 0x9701d43a, 0x1210343a, 0x9711d43a, 1330 0x1600353b, 0x9301d53b, 0x1610353b, 0x9311d53b, 1331 0x1600363c, 0x9301d63c, 0x1610363c, 0x9311d63c, 1332 0x1200373d, 0x9701d73d, 0x1210373d, 0x9711d73d, 1333 0x1200383e, 0x9701d83e, 0x1210383e, 0x9711d83e, 1334 0x1600393f, 0x9301d93f, 0x1610393f, 0x9311d93f, 1335 0x02004040, 0x8301e040, 0x16103a40, 0x9311da40, 1336 0x06004141, 0x8701e141, 0x12103b41, 0x9711db41, 1337 0x06004242, 0x8701e242, 0x16103c42, 0x9311dc42, 1338 0x02004343, 0x8301e343, 0x12103d43, 0x9711dd43, 1339 0x06004444, 0x8701e444, 0x12103e44, 0x9711de44, 1340 0x02004545, 0x8301e545, 0x16103f45, 0x9311df45, 1341 0x02004646, 0x8301e646, 0x12104046, 0x9311e046, 1342 0x06004747, 0x8701e747, 0x16104147, 0x9711e147, 1343 0x06004848, 0x8701e848, 0x16104248, 0x9711e248, 1344 0x02004949, 0x8301e949, 0x12104349, 0x9311e349, 1345 0x1600444a, 0x9701e44a, 0x1610444a, 0x9711e44a, 1346 0x1200454b, 0x9301e54b, 0x1210454b, 0x9311e54b, 1347 0x1200464c, 0x9301e64c, 0x1210464c, 0x9311e64c, 1348 0x1600474d, 0x9701e74d, 0x1610474d, 0x9711e74d, 1349 0x1600484e, 0x9701e84e, 0x1610484e, 0x9711e84e, 1350 0x1200494f, 0x9301e94f, 0x1210494f, 0x9311e94f, 1351 0x06005050, 0x8701f050, 0x12104a50, 0x9311ea50, 1352 0x02005151, 0x8301f151, 0x16104b51, 0x9711eb51, 1353 0x02005252, 0x8301f252, 0x12104c52, 0x9311ec52, 1354 0x06005353, 0x8701f353, 0x16104d53, 0x9711ed53, 1355 0x02005454, 0x8301f454, 0x16104e54, 0x9711ee54, 1356 0x06005555, 0x8701f555, 0x12104f55, 0x9311ef55, 1357 0x06005656, 0x8701f656, 0x16105056, 0x9711f056, 1358 0x02005757, 0x8301f757, 0x12105157, 0x9311f157, 1359 0x02005858, 0x8301f858, 0x12105258, 0x9311f258, 1360 0x06005959, 0x8701f959, 0x16105359, 0x9711f359, 1361 0x1200545a, 0x9301f45a, 0x1210545a, 0x9311f45a, 1362 0x1600555b, 0x9701f55b, 0x1610555b, 0x9711f55b, 1363 0x1600565c, 0x9701f65c, 0x1610565c, 0x9711f65c, 1364 0x1200575d, 0x9301f75d, 0x1210575d, 0x9311f75d, 1365 0x1200585e, 0x9301f85e, 0x1210585e, 0x9311f85e, 1366 0x1600595f, 0x9701f95f, 0x1610595f, 0x9711f95f, 1367 0x06006060, 0x47010060, 0x16105a60, 0x9711fa60, 1368 0x02006161, 0x03010161, 0x12105b61, 0x9311fb61, 1369 0x02006262, 0x03010262, 0x16105c62, 0x9711fc62, 1370 0x06006363, 0x07010363, 0x12105d63, 0x9311fd63, 1371 0x02006464, 0x03010464, 0x12105e64, 0x9311fe64, 1372 0x06006565, 0x07010565, 0x16105f65, 0x9711ff65, 1373 0x06006666, 0x07010666, 0x16106066, 0x57110066, 1374 0x02006767, 0x03010767, 0x12106167, 0x13110167, 1375 0x02006868, 0x03010868, 0x12106268, 0x13110268, 1376 0x06006969, 0x07010969, 0x16106369, 0x17110369, 1377 0x1200646a, 0x1301046a, 0x1210646a, 0x1311046a, 1378 0x1600656b, 0x1701056b, 0x1610656b, 0x1711056b, 1379 0x1600666c, 0x1701066c, 0x1610666c, 0x1711066c, 1380 0x1200676d, 0x1301076d, 0x1210676d, 0x1311076d, 1381 0x1200686e, 0x1301086e, 0x1210686e, 0x1311086e, 1382 0x1600696f, 0x1701096f, 0x1610696f, 0x1711096f, 1383 0x02007070, 0x03011070, 0x16106a70, 0x17110a70, 1384 0x06007171, 0x07011171, 0x12106b71, 0x13110b71, 1385 0x06007272, 0x07011272, 0x16106c72, 0x17110c72, 1386 0x02007373, 0x03011373, 0x12106d73, 0x13110d73, 1387 0x06007474, 0x07011474, 0x12106e74, 0x13110e74, 1388 0x02007575, 0x03011575, 0x16106f75, 0x17110f75, 1389 0x02007676, 0x03011676, 0x12107076, 0x13111076, 1390 0x06007777, 0x07011777, 0x16107177, 0x17111177, 1391 0x06007878, 0x07011878, 0x16107278, 0x17111278, 1392 0x02007979, 0x03011979, 0x12107379, 0x13111379, 1393 0x1600747a, 0x1701147a, 0x1610747a, 0x1711147a, 1394 0x1200757b, 0x1301157b, 0x1210757b, 0x1311157b, 1395 0x1200767c, 0x1301167c, 0x1210767c, 0x1311167c, 1396 0x1600777d, 0x1701177d, 0x1610777d, 0x1711177d, 1397 0x1600787e, 0x1701187e, 0x1610787e, 0x1711187e, 1398 0x1200797f, 0x1301197f, 0x1210797f, 0x1311197f, 1399 0x82008080, 0x03012080, 0x12107a80, 0x13111a80, 1400 0x86008181, 0x07012181, 0x16107b81, 0x17111b81, 1401 0x86008282, 0x07012282, 0x12107c82, 0x13111c82, 1402 0x82008383, 0x03012383, 0x16107d83, 0x17111d83, 1403 0x86008484, 0x07012484, 0x16107e84, 0x17111e84, 1404 0x82008585, 0x03012585, 0x12107f85, 0x13111f85, 1405 0x82008686, 0x03012686, 0x92108086, 0x13112086, 1406 0x86008787, 0x07012787, 0x96108187, 0x17112187, 1407 0x86008888, 0x07012888, 0x96108288, 0x17112288, 1408 0x82008989, 0x03012989, 0x92108389, 0x13112389, 1409 0x9600848a, 0x1701248a, 0x9610848a, 0x1711248a, 1410 0x9200858b, 0x1301258b, 0x9210858b, 0x1311258b, 1411 0x9200868c, 0x1301268c, 0x9210868c, 0x1311268c, 1412 0x9600878d, 0x1701278d, 0x9610878d, 0x1711278d, 1413 0x9600888e, 0x1701288e, 0x9610888e, 0x1711288e, 1414 0x9200898f, 0x1301298f, 0x9210898f, 0x1311298f, 1415 0x86009090, 0x07013090, 0x92108a90, 0x13112a90, 1416 0x82009191, 0x03013191, 0x96108b91, 0x17112b91, 1417 0x82009292, 0x03013292, 0x92108c92, 0x13112c92, 1418 0x86009393, 0x07013393, 0x96108d93, 0x17112d93, 1419 0x82009494, 0x03013494, 0x96108e94, 0x17112e94, 1420 0x86009595, 0x07013595, 0x92108f95, 0x13112f95, 1421 0x86009696, 0x07013696, 0x96109096, 0x17113096, 1422 0x82009797, 0x03013797, 0x92109197, 0x13113197, 1423 0x82009898, 0x03013898, 0x92109298, 0x13113298, 1424 0x86009999, 0x07013999, 0x96109399, 0x17113399, 1425 0x1300349a, 0x1301349a, 0x1310349a, 0x1311349a, 1426 0x1700359b, 0x1701359b, 0x1710359b, 0x1711359b, 1427 0x1700369c, 0x1701369c, 0x1710369c, 0x1711369c, 1428 0x1300379d, 0x1301379d, 0x1310379d, 0x1311379d, 1429 0x1300389e, 0x1301389e, 0x1310389e, 0x1311389e, 1430 0x1700399f, 0x1701399f, 0x1710399f, 0x1711399f, 1431 0x030040a0, 0x030140a0, 0x17103aa0, 0x17113aa0, 1432 0x070041a1, 0x070141a1, 0x13103ba1, 0x13113ba1, 1433 0x070042a2, 0x070142a2, 0x17103ca2, 0x17113ca2, 1434 0x030043a3, 0x030143a3, 0x13103da3, 0x13113da3, 1435 0x070044a4, 0x070144a4, 0x13103ea4, 0x13113ea4, 1436 0x030045a5, 0x030145a5, 0x17103fa5, 0x17113fa5, 1437 0x030046a6, 0x030146a6, 0x131040a6, 0x131140a6, 1438 0x070047a7, 0x070147a7, 0x171041a7, 0x171141a7, 1439 0x070048a8, 0x070148a8, 0x171042a8, 0x171142a8, 1440 0x030049a9, 0x030149a9, 0x131043a9, 0x131143a9, 1441 0x170044aa, 0x170144aa, 0x171044aa, 0x171144aa, 1442 0x130045ab, 0x130145ab, 0x131045ab, 0x131145ab, 1443 0x130046ac, 0x130146ac, 0x131046ac, 0x131146ac, 1444 0x170047ad, 0x170147ad, 0x171047ad, 0x171147ad, 1445 0x170048ae, 0x170148ae, 0x171048ae, 0x171148ae, 1446 0x130049af, 0x130149af, 0x131049af, 0x131149af, 1447 0x070050b0, 0x070150b0, 0x13104ab0, 0x13114ab0, 1448 0x030051b1, 0x030151b1, 0x17104bb1, 0x17114bb1, 1449 0x030052b2, 0x030152b2, 0x13104cb2, 0x13114cb2, 1450 0x070053b3, 0x070153b3, 0x17104db3, 0x17114db3, 1451 0x030054b4, 0x030154b4, 0x17104eb4, 0x17114eb4, 1452 0x070055b5, 0x070155b5, 0x13104fb5, 0x13114fb5, 1453 0x070056b6, 0x070156b6, 0x171050b6, 0x171150b6, 1454 0x030057b7, 0x030157b7, 0x131051b7, 0x131151b7, 1455 0x030058b8, 0x030158b8, 0x131052b8, 0x131152b8, 1456 0x070059b9, 0x070159b9, 0x171053b9, 0x171153b9, 1457 0x130054ba, 0x130154ba, 0x131054ba, 0x131154ba, 1458 0x170055bb, 0x170155bb, 0x171055bb, 0x171155bb, 1459 0x170056bc, 0x170156bc, 0x171056bc, 0x171156bc, 1460 0x130057bd, 0x130157bd, 0x131057bd, 0x131157bd, 1461 0x130058be, 0x130158be, 0x131058be, 0x131158be, 1462 0x170059bf, 0x170159bf, 0x171059bf, 0x171159bf, 1463 0x070060c0, 0x070160c0, 0x17105ac0, 0x17115ac0, 1464 0x030061c1, 0x030161c1, 0x13105bc1, 0x13115bc1, 1465 0x030062c2, 0x030162c2, 0x17105cc2, 0x17115cc2, 1466 0x070063c3, 0x070163c3, 0x13105dc3, 0x13115dc3, 1467 0x030064c4, 0x030164c4, 0x13105ec4, 0x13115ec4, 1468 0x070065c5, 0x070165c5, 0x17105fc5, 0x17115fc5, 1469 0x070066c6, 0x070166c6, 0x171060c6, 0x171160c6, 1470 0x030067c7, 0x030167c7, 0x131061c7, 0x131161c7, 1471 0x030068c8, 0x030168c8, 0x131062c8, 0x131162c8, 1472 0x070069c9, 0x070169c9, 0x171063c9, 0x171163c9, 1473 0x130064ca, 0x130164ca, 0x131064ca, 0x131164ca, 1474 0x170065cb, 0x170165cb, 0x171065cb, 0x171165cb, 1475 0x170066cc, 0x170166cc, 0x171066cc, 0x171166cc, 1476 0x130067cd, 0x130167cd, 0x131067cd, 0x131167cd, 1477 0x130068ce, 0x130168ce, 0x131068ce, 0x131168ce, 1478 0x170069cf, 0x170169cf, 0x171069cf, 0x171169cf, 1479 0x030070d0, 0x030170d0, 0x17106ad0, 0x17116ad0, 1480 0x070071d1, 0x070171d1, 0x13106bd1, 0x13116bd1, 1481 0x070072d2, 0x070172d2, 0x17106cd2, 0x17116cd2, 1482 0x030073d3, 0x030173d3, 0x13106dd3, 0x13116dd3, 1483 0x070074d4, 0x070174d4, 0x13106ed4, 0x13116ed4, 1484 0x030075d5, 0x030175d5, 0x17106fd5, 0x17116fd5, 1485 0x030076d6, 0x030176d6, 0x131070d6, 0x131170d6, 1486 0x070077d7, 0x070177d7, 0x171071d7, 0x171171d7, 1487 0x070078d8, 0x070178d8, 0x171072d8, 0x171172d8, 1488 0x030079d9, 0x030179d9, 0x131073d9, 0x131173d9, 1489 0x170074da, 0x170174da, 0x171074da, 0x171174da, 1490 0x130075db, 0x130175db, 0x131075db, 0x131175db, 1491 0x130076dc, 0x130176dc, 0x131076dc, 0x131176dc, 1492 0x170077dd, 0x170177dd, 0x171077dd, 0x171177dd, 1493 0x170078de, 0x170178de, 0x171078de, 0x171178de, 1494 0x130079df, 0x130179df, 0x131079df, 0x131179df, 1495 0x830080e0, 0x830180e0, 0x13107ae0, 0x13117ae0, 1496 0x870081e1, 0x870181e1, 0x17107be1, 0x17117be1, 1497 0x870082e2, 0x870182e2, 0x13107ce2, 0x13117ce2, 1498 0x830083e3, 0x830183e3, 0x17107de3, 0x17117de3, 1499 0x870084e4, 0x870184e4, 0x17107ee4, 0x17117ee4, 1500 0x830085e5, 0x830185e5, 0x13107fe5, 0x13117fe5, 1501 0x830086e6, 0x830186e6, 0x931080e6, 0x931180e6, 1502 0x870087e7, 0x870187e7, 0x971081e7, 0x971181e7, 1503 0x870088e8, 0x870188e8, 0x971082e8, 0x971182e8, 1504 0x830089e9, 0x830189e9, 0x931083e9, 0x931183e9, 1505 0x970084ea, 0x970184ea, 0x971084ea, 0x971184ea, 1506 0x930085eb, 0x930185eb, 0x931085eb, 0x931185eb, 1507 0x930086ec, 0x930186ec, 0x931086ec, 0x931186ec, 1508 0x970087ed, 0x970187ed, 0x971087ed, 0x971187ed, 1509 0x970088ee, 0x970188ee, 0x971088ee, 0x971188ee, 1510 0x930089ef, 0x930189ef, 0x931089ef, 0x931189ef, 1511 0x870090f0, 0x870190f0, 0x93108af0, 0x93118af0, 1512 0x830091f1, 0x830191f1, 0x97108bf1, 0x97118bf1, 1513 0x830092f2, 0x830192f2, 0x93108cf2, 0x93118cf2, 1514 0x870093f3, 0x870193f3, 0x97108df3, 0x97118df3, 1515 0x830094f4, 0x830194f4, 0x97108ef4, 0x97118ef4, 1516 0x870095f5, 0x870195f5, 0x93108ff5, 0x93118ff5, 1517 0x870096f6, 0x870196f6, 0x971090f6, 0x971190f6, 1518 0x830097f7, 0x830197f7, 0x931091f7, 0x931191f7, 1519 0x830098f8, 0x830198f8, 0x931092f8, 0x931192f8, 1520 0x870099f9, 0x870199f9, 0x971093f9, 0x971193f9, 1521 0x930094fa, 0x930194fa, 0x931094fa, 0x931194fa, 1522 0x970095fb, 0x970195fb, 0x971095fb, 0x971195fb, 1523 0x970096fc, 0x970196fc, 0x971096fc, 0x971196fc, 1524 0x930097fd, 0x930197fd, 0x931097fd, 0x931197fd, 1525 0x930098fe, 0x930198fe, 0x931098fe, 0x931198fe, 1526 0x970099ff, 0x970199ff, 0x971099ff, 0x971199ff, 1527 }; 1528 1529 MK_INSN(das, "das"); 1530 1531 for (i = 0; i < 1024; ++i) { 1532 unsigned tmp = test_cases[i]; 1533 inregs.eax = tmp & 0xff; 1534 inregs.eflags = (tmp >> 16) & 0xff; 1535 exec_in_big_real_mode(&inregs, &outregs, 1536 insn_das, 1537 insn_das_end - insn_das); 1538 1539 if (!regs_equal(&inregs, &outregs, R_AX) 1540 || outregs.eax != ((tmp >> 8) & 0xff) 1541 || (outregs.eflags & 0xff) != (tmp >> 24)) { 1542 print_serial("DAS Test: FAIL\n"); 1543 return; 1544 } 1545 } 1546 print_serial("DAS Test: PASS\n"); 1547 } 1548 1549 void realmode_start(void) 1550 { 1551 test_null(); 1552 1553 test_shld(); 1554 test_push_pop(); 1555 test_pusha_popa(); 1556 test_mov_imm(); 1557 test_cmp_imm(); 1558 test_add_imm(); 1559 test_sub_imm(); 1560 test_xor_imm(); 1561 test_io(); 1562 test_eflags_insn(); 1563 test_jcc_short(); 1564 test_jcc_near(); 1565 /* test_call() uses short jump so call it after testing jcc */ 1566 test_call(); 1567 /* long jmp test uses call near so test it after testing call */ 1568 test_long_jmp(); 1569 test_xchg(); 1570 test_iret(); 1571 test_int(); 1572 test_imul(); 1573 test_mul(); 1574 test_div(); 1575 test_idiv(); 1576 test_loopcc(); 1577 test_cbw(); 1578 test_das(); 1579 1580 exit(0); 1581 } 1582 1583 unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff }; 1584 1585 struct __attribute__((packed)) { 1586 unsigned short limit; 1587 void *base; 1588 } r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt }; 1589 1590 asm( 1591 ".section .init \n\t" 1592 1593 ".code32 \n\t" 1594 1595 "mb_magic = 0x1BADB002 \n\t" 1596 "mb_flags = 0x0 \n\t" 1597 1598 "# multiboot header \n\t" 1599 ".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t" 1600 1601 ".globl start \n\t" 1602 ".data \n\t" 1603 ". = . + 4096 \n\t" 1604 "stacktop: \n\t" 1605 1606 ".text \n\t" 1607 "start: \n\t" 1608 "lgdt r_gdt_descr \n\t" 1609 "ljmp $8, $1f; 1: \n\t" 1610 ".code16gcc \n\t" 1611 "mov $16, %eax \n\t" 1612 "mov %ax, %ds \n\t" 1613 "mov %ax, %es \n\t" 1614 "mov %ax, %fs \n\t" 1615 "mov %ax, %gs \n\t" 1616 "mov %ax, %ss \n\t" 1617 "mov %cr0, %eax \n\t" 1618 "btc $0, %eax \n\t" 1619 "mov %eax, %cr0 \n\t" 1620 "ljmp $0, $realmode_entry \n\t" 1621 1622 "realmode_entry: \n\t" 1623 1624 "xor %ax, %ax \n\t" 1625 "mov %ax, %ds \n\t" 1626 "mov %ax, %es \n\t" 1627 "mov %ax, %ss \n\t" 1628 "mov %ax, %fs \n\t" 1629 "mov %ax, %gs \n\t" 1630 "mov $stacktop, %esp\n\t" 1631 "ljmp $0, $realmode_start \n\t" 1632 1633 ".code16gcc \n\t" 1634 ); 1635