From 1a4de9dd58201bb57a07ea931d1764064fc52e64 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 22 Sep 2018 00:32:03 -0700 Subject: 4588 --- html/subx/013direct_addressing.cc.html | 289 +++++++++++++++++++++++---------- 1 file changed, 205 insertions(+), 84 deletions(-) (limited to 'html/subx/013direct_addressing.cc.html') diff --git a/html/subx/013direct_addressing.cc.html b/html/subx/013direct_addressing.cc.html index 8b251309..0c945efa 100644 --- a/html/subx/013direct_addressing.cc.html +++ b/html/subx/013direct_addressing.cc.html @@ -327,7 +327,7 @@ if ('onhashchange' in window) { 262 //:: compare (cmp) 263 264 :(before "End Initialize Op Names(name)") -265 put(name, "39", "set SF if rm32 < r32"); +265 put(name, "39", "compare: set SF if rm32 < r32"); 266 267 :(scenario compare_r32_with_r32_greater) 268 % Reg[EAX].i = 0x0a0b0c0d; @@ -435,92 +435,213 @@ if ('onhashchange' in window) { 370 break; 371 } 372 -373 //:: push +373 //:: increment 374 375 :(before "End Initialize Op Names(name)") -376 put(name, "50", "push R0 (EAX) to stack"); -377 put(name, "51", "push R1 (ECX) to stack"); -378 put(name, "52", "push R2 (EDX) to stack"); -379 put(name, "53", "push R3 (EBX) to stack"); -380 put(name, "54", "push R4 (ESP) to stack"); -381 put(name, "55", "push R5 (EBP) to stack"); -382 put(name, "56", "push R6 (ESI) to stack"); -383 put(name, "57", "push R7 (EDI) to stack"); +376 put(name, "40", "increment R0 (EAX)"); +377 put(name, "41", "increment R1 (ECX)"); +378 put(name, "42", "increment R2 (EDX)"); +379 put(name, "43", "increment R3 (EBX)"); +380 put(name, "44", "increment R4 (ESP)"); +381 put(name, "45", "increment R5 (EBP)"); +382 put(name, "46", "increment R6 (ESI)"); +383 put(name, "47", "increment R7 (EDI)"); 384 -385 :(scenario push_r32) -386 % Reg[ESP].u = 0x64; -387 % Reg[EBX].i = 0x0000000a; -388 == 0x1 -389 # op ModR/M SIB displacement immediate -390 53 # push EBX to stack -391 +run: push EBX -392 +run: decrementing ESP to 0x00000060 -393 +run: pushing value 0x0000000a -394 -395 :(before "End Single-Byte Opcodes") -396 case 0x50: -397 case 0x51: -398 case 0x52: -399 case 0x53: -400 case 0x54: -401 case 0x55: -402 case 0x56: -403 case 0x57: { // push r32 to stack -404 uint8_t reg = op & 0x7; -405 trace(90, "run") << "push " << rname(reg) << end(); -406 //? cerr << "push: " << NUM(reg) << ": " << Reg[reg].u << " => " << Reg[ESP].u << '\n'; -407 push(Reg[reg].u); -408 break; -409 } -410 -411 //:: pop -412 -413 :(before "End Initialize Op Names(name)") -414 put(name, "58", "pop top of stack to R0 (EAX)"); -415 put(name, "59", "pop top of stack to R1 (ECX)"); -416 put(name, "5a", "pop top of stack to R2 (EDX)"); -417 put(name, "5b", "pop top of stack to R3 (EBX)"); -418 put(name, "5c", "pop top of stack to R4 (ESP)"); -419 put(name, "5d", "pop top of stack to R5 (EBP)"); -420 put(name, "5e", "pop top of stack to R6 (ESI)"); -421 put(name, "5f", "pop top of stack to R7 (EDI)"); -422 -423 :(scenario pop_r32) -424 % Reg[ESP].u = 0x60; -425 % write_mem_i32(0x60, 0x0000000a); -426 == 0x1 # code segment -427 # op ModR/M SIB displacement immediate -428 5b # pop stack to EBX -429 == 0x60 # data segment -430 0a 00 00 00 # 0x0a -431 +run: pop into EBX -432 +run: popping value 0x0000000a -433 +run: incrementing ESP to 0x00000064 -434 -435 :(before "End Single-Byte Opcodes") -436 case 0x58: -437 case 0x59: -438 case 0x5a: -439 case 0x5b: -440 case 0x5c: -441 case 0x5d: -442 case 0x5e: -443 case 0x5f: { // pop stack into r32 -444 uint8_t reg = op & 0x7; -445 trace(90, "run") << "pop into " << rname(reg) << end(); -446 //? cerr << "pop from " << Reg[ESP].u << '\n'; -447 Reg[reg].u = pop(); -448 //? cerr << "=> " << NUM(reg) << ": " << Reg[reg].u << '\n'; -449 break; -450 } -451 :(code) -452 uint32_t pop() { -453 uint32_t result = read_mem_u32(Reg[ESP].u); -454 trace(90, "run") << "popping value 0x" << HEXWORD << result << end(); -455 Reg[ESP].u += 4; -456 trace(90, "run") << "incrementing ESP to 0x" << HEXWORD << Reg[ESP].u << end(); -457 return result; -458 } +385 :(scenario increment_r32) +386 % Reg[ECX].u = 0x1f; +387 == 0x1 # code segment +388 # op ModR/M SIB displacement immediate +389 41 # increment ECX +390 +run: increment ECX +391 +run: storing value 0x00000020 +392 +393 :(before "End Single-Byte Opcodes") +394 case 0x40: +395 case 0x41: +396 case 0x42: +397 case 0x43: +398 case 0x44: +399 case 0x45: +400 case 0x46: +401 case 0x47: { // increment r32 +402 uint8_t reg = op & 0x7; +403 trace(90, "run") << "increment " << rname(reg) << end(); +404 ++Reg[reg].u; +405 trace(90, "run") << "storing value 0x" << HEXWORD << Reg[reg].u << end(); +406 break; +407 } +408 +409 :(before "End Initialize Op Names(name)") +410 put(name, "ff", "inc/dec/jump/push/call rm32 based on subop"); +411 +412 :(scenario increment_rm32) +413 % Reg[EAX].u = 0x20; +414 == 0x1 # code segment +415 # op ModR/M SIB displacement immediate +416 ff c0 # increment EAX +417 # ModR/M in binary: 11 (direct mode) 000 (subop inc) 000 (EAX) +418 +run: increment r/m32 +419 +run: r/m32 is EAX +420 +run: storing value 0x00000021 +421 +422 :(before "End Single-Byte Opcodes") +423 case 0xff: { +424 uint8_t modrm = next(); +425 uint8_t subop = (modrm>>3)&0x7; // middle 3 'reg opcode' bits +426 switch (subop) { +427 case 0: { // increment r/m32 +428 trace(90, "run") << "increment r/m32" << end(); +429 int32_t* arg = effective_address(modrm); +430 ++*arg; +431 trace(90, "run") << "storing value 0x" << HEXWORD << *arg << end(); +432 break; +433 } +434 // End Op ff Subops +435 } +436 break; +437 } +438 +439 //:: decrement +440 +441 :(before "End Initialize Op Names(name)") +442 put(name, "48", "decrement R0 (EAX)"); +443 put(name, "49", "decrement R1 (ECX)"); +444 put(name, "4a", "decrement R2 (EDX)"); +445 put(name, "4b", "decrement R3 (EBX)"); +446 put(name, "4c", "decrement R4 (ESP)"); +447 put(name, "4d", "decrement R5 (EBP)"); +448 put(name, "4e", "decrement R6 (ESI)"); +449 put(name, "4f", "decrement R7 (EDI)"); +450 +451 :(scenario decrement_r32) +452 % Reg[ECX].u = 0x1f; +453 == 0x1 # code segment +454 # op ModR/M SIB displacement immediate +455 49 # decrement ECX +456 +run: decrement ECX +457 +run: storing value 0x0000001e +458 +459 :(before "End Single-Byte Opcodes") +460 case 0x48: +461 case 0x49: +462 case 0x4a: +463 case 0x4b: +464 case 0x4c: +465 case 0x4d: +466 case 0x4e: +467 case 0x4f: { // decrement r32 +468 uint8_t reg = op & 0x7; +469 trace(90, "run") << "decrement " << rname(reg) << end(); +470 --Reg[reg].u; +471 trace(90, "run") << "storing value 0x" << HEXWORD << Reg[reg].u << end(); +472 break; +473 } +474 +475 :(scenario decrement_rm32) +476 % Reg[EAX].u = 0x20; +477 == 0x1 # code segment +478 # op ModR/M SIB displacement immediate +479 ff c8 # decrement EAX +480 # ModR/M in binary: 11 (direct mode) 001 (subop inc) 000 (EAX) +481 +run: decrement r/m32 +482 +run: r/m32 is EAX +483 +run: storing value 0x0000001f +484 +485 :(before "End Op ff Subops") +486 case 1: { // decrement r/m32 +487 trace(90, "run") << "decrement r/m32" << end(); +488 int32_t* arg = effective_address(modrm); +489 --*arg; +490 trace(90, "run") << "storing value 0x" << HEXWORD << *arg << end(); +491 break; +492 } +493 +494 //:: push +495 +496 :(before "End Initialize Op Names(name)") +497 put(name, "50", "push R0 (EAX) to stack"); +498 put(name, "51", "push R1 (ECX) to stack"); +499 put(name, "52", "push R2 (EDX) to stack"); +500 put(name, "53", "push R3 (EBX) to stack"); +501 put(name, "54", "push R4 (ESP) to stack"); +502 put(name, "55", "push R5 (EBP) to stack"); +503 put(name, "56", "push R6 (ESI) to stack"); +504 put(name, "57", "push R7 (EDI) to stack"); +505 +506 :(scenario push_r32) +507 % Reg[ESP].u = 0x64; +508 % Reg[EBX].i = 0x0000000a; +509 == 0x1 +510 # op ModR/M SIB displacement immediate +511 53 # push EBX to stack +512 +run: push EBX +513 +run: decrementing ESP to 0x00000060 +514 +run: pushing value 0x0000000a +515 +516 :(before "End Single-Byte Opcodes") +517 case 0x50: +518 case 0x51: +519 case 0x52: +520 case 0x53: +521 case 0x54: +522 case 0x55: +523 case 0x56: +524 case 0x57: { // push r32 to stack +525 uint8_t reg = op & 0x7; +526 trace(90, "run") << "push " << rname(reg) << end(); +527 //? cerr << "push: " << NUM(reg) << ": " << Reg[reg].u << " => " << Reg[ESP].u << '\n'; +528 push(Reg[reg].u); +529 break; +530 } +531 +532 //:: pop +533 +534 :(before "End Initialize Op Names(name)") +535 put(name, "58", "pop top of stack to R0 (EAX)"); +536 put(name, "59", "pop top of stack to R1 (ECX)"); +537 put(name, "5a", "pop top of stack to R2 (EDX)"); +538 put(name, "5b", "pop top of stack to R3 (EBX)"); +539 put(name, "5c", "pop top of stack to R4 (ESP)"); +540 put(name, "5d", "pop top of stack to R5 (EBP)"); +541 put(name, "5e", "pop top of stack to R6 (ESI)"); +542 put(name, "5f", "pop top of stack to R7 (EDI)"); +543 +544 :(scenario pop_r32) +545 % Reg[ESP].u = 0x60; +546 % write_mem_i32(0x60, 0x0000000a); +547 == 0x1 # code segment +548 # op ModR/M SIB displacement immediate +549 5b # pop stack to EBX +550 == 0x60 # data segment +551 0a 00 00 00 # 0x0a +552 +run: pop into EBX +553 +run: popping value 0x0000000a +554 +run: incrementing ESP to 0x00000064 +555 +556 :(before "End Single-Byte Opcodes") +557 case 0x58: +558 case 0x59: +559 case 0x5a: +560 case 0x5b: +561 case 0x5c: +562 case 0x5d: +563 case 0x5e: +564 case 0x5f: { // pop stack into r32 +565 uint8_t reg = op & 0x7; +566 trace(90, "run") << "pop into " << rname(reg) << end(); +567 //? cerr << "pop from " << Reg[ESP].u << '\n'; +568 Reg[reg].u = pop(); +569 //? cerr << "=> " << NUM(reg) << ": " << Reg[reg].u << '\n'; +570 break; +571 } +572 :(code) +573 uint32_t pop() { +574 uint32_t result = read_mem_u32(Reg[ESP].u); +575 trace(90, "run") << "popping value 0x" << HEXWORD << result << end(); +576 Reg[ESP].u += 4; +577 trace(90, "run") << "incrementing ESP to 0x" << HEXWORD << Reg[ESP].u << end(); +578 return result; +579 } -- cgit 1.4.1-2-gfad0