177 lines
3.9 KiB
JavaScript
177 lines
3.9 KiB
JavaScript
/*
|
|
* This file contains functions to decode the modrm and sib bytes
|
|
*
|
|
* These functions return a virtual address
|
|
*
|
|
* Gets #included by cpu.macro.js
|
|
*/
|
|
"use strict";
|
|
|
|
var modrm_resolve16,
|
|
modrm_resolve32;
|
|
|
|
(function() {
|
|
|
|
var modrm_table16 = Array(0xC0),
|
|
modrm_table32 = Array(0xC0),
|
|
sib_table = Array(0x100);
|
|
|
|
#define ds get_seg_prefix(reg_ds)
|
|
#define ss get_seg_prefix(reg_ss)
|
|
|
|
#define eax reg32s[reg_eax]
|
|
#define ecx reg32s[reg_ecx]
|
|
#define edx reg32s[reg_edx]
|
|
#define ebx reg32s[reg_ebx]
|
|
#define esp reg32s[reg_esp]
|
|
#define ebp reg32s[reg_ebp]
|
|
#define esi reg32s[reg_esi]
|
|
#define edi reg32s[reg_edi]
|
|
|
|
#define imm32 read_imm32s()
|
|
#define imm16 read_imm16()
|
|
#define imm8 read_imm8()
|
|
|
|
#define entry16(row, seg, value)\
|
|
entry16_(0x00 | row, seg + ((value) & 0xFFFF))\
|
|
entry16_(0x40 | row, seg + ((value) + read_imm8s() & 0xFFFF))\
|
|
entry16_(0x80 | row, seg + ((value) + read_imm16() & 0xFFFF))\
|
|
|
|
#define entry16_(n, offset)\
|
|
modrm_table16[n] = function() { return offset | 0; };
|
|
|
|
|
|
entry16(0, ds, reg16[reg_bx] + reg16[reg_si])
|
|
entry16(1, ds, reg16[reg_bx] + reg16[reg_di])
|
|
entry16(2, ss, reg16[reg_bp] + reg16[reg_si])
|
|
entry16(3, ss, reg16[reg_bp] + reg16[reg_di])
|
|
entry16(4, ds, reg16[reg_si])
|
|
entry16(5, ds, reg16[reg_di])
|
|
entry16(6, ss, reg16[reg_bp])
|
|
entry16(7, ds, reg16[reg_bx])
|
|
|
|
#define entry32(row, value)\
|
|
entry32_(0x00 | row, (value))\
|
|
entry32_(0x40 | row, (value) + read_imm8s())\
|
|
entry32_(0x80 | row, (value) + read_imm32s())\
|
|
|
|
#define entry32_(n, offset)\
|
|
modrm_table32[n] = function() { return offset | 0; };
|
|
|
|
|
|
entry32(0, ds + eax);
|
|
entry32(1, ds + ecx);
|
|
entry32(2, ds + edx);
|
|
entry32(3, ds + ebx);
|
|
entry32(4, getsib(false));
|
|
entry32(5, ss + ebp);
|
|
entry32(6, ds + esi);
|
|
entry32(7, ds + edi);
|
|
|
|
|
|
// special cases
|
|
modrm_table16[0x00 | 6] = function() { return ds + read_imm16() | 0; }
|
|
|
|
modrm_table32[0x00 | 5] = function() { return ds + read_imm32s() | 0; };
|
|
|
|
modrm_table32[0x00 | 4] = function() { return getsib(false) | 0; };
|
|
modrm_table32[0x40 | 4] = function() { return getsib(true) + read_imm8s() | 0; };
|
|
modrm_table32[0x80 | 4] = function() { return getsib(true) + read_imm32s() | 0; };
|
|
|
|
|
|
for(var low = 0; low < 8; low++)
|
|
{
|
|
for(var high = 0; high < 3; high++)
|
|
{
|
|
for(var i = 1; i < 8; i++)
|
|
{
|
|
var x = low | high << 6;
|
|
|
|
modrm_table32[x | i << 3] = modrm_table32[x];
|
|
modrm_table16[x | i << 3] = modrm_table16[x];
|
|
}
|
|
}
|
|
}
|
|
|
|
#define entry_sib(n, reg1)\
|
|
entry_sib2(0x00 | n << 3, reg1)\
|
|
entry_sib2(0x40 | n << 3, reg1 << 1)\
|
|
entry_sib2(0x80 | n << 3, reg1 << 2)\
|
|
entry_sib2(0xC0 | n << 3, reg1 << 3)
|
|
|
|
#define entry_sib2(n, offset)\
|
|
entry_sib3(n | 0, (offset) + ds + eax)\
|
|
entry_sib3(n | 1, (offset) + ds + ecx)\
|
|
entry_sib3(n | 2, (offset) + ds + edx)\
|
|
entry_sib3(n | 3, (offset) + ds + ebx)\
|
|
entry_sib3(n | 4, (offset) + ss + esp)\
|
|
entry_sib3(n | 5, (offset) + (mod ? ss + ebp : ds + imm32))\
|
|
entry_sib3(n | 6, (offset) + ds + esi)\
|
|
entry_sib3(n | 7, (offset) + ds + edi)
|
|
|
|
#define entry_sib3(n, offset)\
|
|
sib_table[n] = function(mod) { return offset | 0; };
|
|
|
|
entry_sib(0, eax);
|
|
entry_sib(1, ecx);
|
|
entry_sib(2, edx);
|
|
entry_sib(3, ebx);
|
|
entry_sib(4, 0);
|
|
entry_sib(5, ebp);
|
|
entry_sib(6, esi);
|
|
entry_sib(7, edi);
|
|
|
|
|
|
/**
|
|
* @param {number} modrm_byte
|
|
* @return {number}
|
|
*/
|
|
modrm_resolve16 = function(modrm_byte)
|
|
{
|
|
return modrm_table16[modrm_byte]();
|
|
}
|
|
|
|
/**
|
|
* @param {number} modrm_byte
|
|
* @return {number}
|
|
*/
|
|
modrm_resolve32 = function(modrm_byte)
|
|
{
|
|
return modrm_table32[modrm_byte]();
|
|
}
|
|
|
|
/**
|
|
* @param {boolean} mod
|
|
* @return {number}
|
|
*/
|
|
function getsib(mod)
|
|
{
|
|
return sib_table[read_imm8()](mod);
|
|
}
|
|
|
|
#undef ds
|
|
#undef ss
|
|
|
|
#undef eax
|
|
#undef ecx
|
|
#undef edx
|
|
#undef ebx
|
|
#undef esp
|
|
#undef ebp
|
|
#undef esi
|
|
#undef edi
|
|
|
|
#undef imm32
|
|
#undef imm16
|
|
#undef imm8
|
|
|
|
#undef entry16
|
|
#undef entry16_
|
|
#undef entry32_
|
|
|
|
#undef entry_sib
|
|
#undef entry_sib2
|
|
#undef entry_sib3
|
|
|
|
})();
|