Restore #gp when accessing null segment, only non-jit (fixes Windows 95 and 98)

This commit is contained in:
Fabian 2020-12-31 19:14:30 -06:00
parent 107c6fef36
commit 1ea2209499
5 changed files with 237 additions and 141 deletions

View file

@ -421,7 +421,7 @@ pub unsafe fn iret(is_16: bool) {
}
switch_cs_real_mode(new_cs);
*instruction_pointer = get_seg(CS) + new_eip;
*instruction_pointer = get_seg_cs() + new_eip;
if is_16 {
update_eflags(new_flags | *flags & !0xFFFF);
@ -474,7 +474,7 @@ pub unsafe fn iret(is_16: bool) {
*flags |= FLAG_VM;
switch_cs_real_mode(new_cs);
*instruction_pointer = get_seg(CS) + (new_eip & 0xFFFF);
*instruction_pointer = get_seg_cs() + (new_eip & 0xFFFF);
if !switch_seg(ES, new_es)
|| !switch_seg(DS, new_ds)
@ -654,7 +654,7 @@ pub unsafe fn iret(is_16: bool) {
*segment_limits.offset(CS as isize) = cs_descriptor.effective_limit();
*segment_offsets.offset(CS as isize) = cs_descriptor.base();
*instruction_pointer = new_eip + get_seg(CS);
*instruction_pointer = new_eip + get_seg_cs();
// iret end
@ -941,7 +941,7 @@ pub unsafe fn call_interrupt_vector(
*segment_limits.offset(CS as isize) = cs_segment_descriptor.effective_limit();
*segment_offsets.offset(CS as isize) = cs_segment_descriptor.base();
*instruction_pointer = get_seg(CS) + offset;
*instruction_pointer = get_seg_cs() + offset;
*flags &= !FLAG_NT & !FLAG_VM & !FLAG_RF & !FLAG_TRAP;
@ -977,7 +977,7 @@ pub unsafe fn call_interrupt_vector(
*flags &= !FLAG_INTERRUPT & !FLAG_AC & !FLAG_TRAP;
switch_cs_real_mode(new_cs);
*instruction_pointer = get_seg(CS) + new_ip;
*instruction_pointer = get_seg_cs() + new_ip;
}
}
@ -1663,15 +1663,17 @@ pub unsafe fn assert_seg_non_null(segment: i32) {
}
}
pub unsafe fn get_seg(segment: i32) -> i32 {
pub unsafe fn get_seg(segment: i32) -> OrPageFault<i32> {
dbg_assert!(segment >= 0 && segment < 8);
if *segment_is_null.offset(segment as isize) {
dbg_assert!(segment != CS && segment != SS);
dbg_log!("#gp: Access null segment");
assert!(false);
//trigger_gp(0); // TODO
dbg_trace();
dbg_assert!(!in_jit, "TODO");
trigger_gp(0);
return Err(());
}
return *segment_offsets.offset(segment as isize);
return Ok(*segment_offsets.offset(segment as isize));
}
pub unsafe fn set_cr0(cr0: i32) {
@ -1783,12 +1785,12 @@ pub unsafe fn get_seg_cs() -> i32 { return *segment_offsets.offset(CS as isize);
#[no_mangle]
pub unsafe fn get_seg_ss() -> i32 { return *segment_offsets.offset(SS as isize); }
pub unsafe fn get_seg_prefix(default_segment: i32) -> i32 {
pub unsafe fn get_seg_prefix(default_segment: i32) -> OrPageFault<i32> {
dbg_assert!(!in_jit);
let prefix = *prefixes as i32 & PREFIX_MASK_SEGMENT;
if 0 != prefix {
if prefix == SEG_PREFIX_ZERO {
return 0;
return Ok(0);
}
else {
return get_seg(prefix - 1);
@ -1799,9 +1801,13 @@ pub unsafe fn get_seg_prefix(default_segment: i32) -> i32 {
};
}
pub unsafe fn get_seg_prefix_ds(offset: i32) -> i32 { return get_seg_prefix(DS) + offset; }
pub unsafe fn get_seg_prefix_ds(offset: i32) -> OrPageFault<i32> {
Ok(get_seg_prefix(DS)? + offset)
}
pub unsafe fn get_seg_prefix_ss(offset: i32) -> i32 { return get_seg_prefix(SS) + offset; }
pub unsafe fn get_seg_prefix_ss(offset: i32) -> OrPageFault<i32> {
Ok(get_seg_prefix(SS)? + offset)
}
pub unsafe fn modrm_resolve(modrm_byte: i32) -> OrPageFault<i32> {
if is_asize_32() { resolve_modrm32(modrm_byte) } else { resolve_modrm16(modrm_byte) }

View file

@ -928,11 +928,15 @@ pub unsafe fn instr16_6D() { insw_no_rep(is_asize_32()); }
#[no_mangle]
pub unsafe fn instr32_6D() { insd_no_rep(is_asize_32()); }
#[no_mangle]
pub unsafe fn instr_6E() { outsb_no_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr_6E() { outsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr16_6F() { outsw_no_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr16_6F() {
outsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
#[no_mangle]
pub unsafe fn instr32_6F() { outsd_no_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr32_6F() {
outsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
#[no_mangle]
pub unsafe fn instr_80_0_mem(addr: i32, imm: i32) {
SAFE_READ_WRITE8!(___, addr, add8(___, imm));
@ -1575,25 +1579,25 @@ pub unsafe fn instr_9F() {
#[no_mangle]
pub unsafe fn instr_A0(moffs: i32) {
// mov
let data = return_on_pagefault!(safe_read8(get_seg_prefix_ds(moffs)));
let data = return_on_pagefault!(safe_read8(return_on_pagefault!(get_seg_prefix_ds(moffs))));
*reg8.offset(AL as isize) = data as u8;
}
#[no_mangle]
pub unsafe fn instr16_A1(moffs: i32) {
// mov
let data = return_on_pagefault!(safe_read16(get_seg_prefix_ds(moffs)));
let data = return_on_pagefault!(safe_read16(return_on_pagefault!(get_seg_prefix_ds(moffs))));
*reg16.offset(AX as isize) = data as u16;
}
#[no_mangle]
pub unsafe fn instr32_A1(moffs: i32) {
let data = return_on_pagefault!(safe_read32s(get_seg_prefix_ds(moffs)));
let data = return_on_pagefault!(safe_read32s(return_on_pagefault!(get_seg_prefix_ds(moffs))));
*reg32.offset(EAX as isize) = data;
}
#[no_mangle]
pub unsafe fn instr_A2(moffs: i32) {
// mov
return_on_pagefault!(safe_write8(
get_seg_prefix_ds(moffs),
return_on_pagefault!(get_seg_prefix_ds(moffs)),
*reg8.offset(AL as isize) as i32
));
}
@ -1601,29 +1605,37 @@ pub unsafe fn instr_A2(moffs: i32) {
pub unsafe fn instr16_A3(moffs: i32) {
// mov
return_on_pagefault!(safe_write16(
get_seg_prefix_ds(moffs),
return_on_pagefault!(get_seg_prefix_ds(moffs)),
*reg16.offset(AX as isize) as i32
));
}
#[no_mangle]
pub unsafe fn instr32_A3(moffs: i32) {
return_on_pagefault!(safe_write32(
get_seg_prefix_ds(moffs),
return_on_pagefault!(get_seg_prefix_ds(moffs)),
*reg32.offset(EAX as isize)
));
}
#[no_mangle]
pub unsafe fn instr_A4() { movsb_no_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr_A4() { movsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr16_A5() { movsw_no_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr16_A5() {
movsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
#[no_mangle]
pub unsafe fn instr32_A5() { movsd_no_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr32_A5() {
movsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
#[no_mangle]
pub unsafe fn instr_A6() { cmpsb_no_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr_A6() { cmpsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr16_A7() { cmpsw_no_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr16_A7() {
cmpsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
#[no_mangle]
pub unsafe fn instr32_A7() { cmpsd_no_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr32_A7() {
cmpsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
#[no_mangle]
pub unsafe fn instr_A8(imm8: i32) { test8(*reg8.offset(AL as isize) as i32, imm8); }
#[no_mangle]
@ -1637,11 +1649,15 @@ pub unsafe fn instr16_AB() { stosw_no_rep(is_asize_32()); }
#[no_mangle]
pub unsafe fn instr32_AB() { stosd_no_rep(is_asize_32()); }
#[no_mangle]
pub unsafe fn instr_AC() { lodsb_no_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr_AC() { lodsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr16_AD() { lodsw_no_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr16_AD() {
lodsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
#[no_mangle]
pub unsafe fn instr32_AD() { lodsd_no_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr32_AD() {
lodsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
#[no_mangle]
pub unsafe fn instr_AE() { scasb_no_rep(is_asize_32()); }
#[no_mangle]
@ -2426,12 +2442,14 @@ pub unsafe fn instr_D7() {
dbg_assert!(!in_jit, "TODO");
if is_asize_32() {
*reg8.offset(AL as isize) = return_on_pagefault!(safe_read8(
get_seg_prefix(DS) + *reg32.offset(EBX as isize) + *reg8.offset(AL as isize) as i32,
return_on_pagefault!(get_seg_prefix(DS))
+ *reg32.offset(EBX as isize)
+ *reg8.offset(AL as isize) as i32,
)) as u8
}
else {
*reg8.offset(AL as isize) = return_on_pagefault!(safe_read8(
get_seg_prefix(DS)
return_on_pagefault!(get_seg_prefix(DS))
+ (*reg16.offset(BX as isize) as i32 + *reg8.offset(AL as isize) as i32 & 0xFFFF),
)) as u8
};
@ -3031,17 +3049,17 @@ pub unsafe fn instr32_F26D() { insd_rep(is_asize_32()); }
#[no_mangle]
pub unsafe fn instr32_F36D() { insd_rep(is_asize_32()); }
#[no_mangle]
pub unsafe fn instr_F26E() { outsb_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr_F26E() { outsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr_F36E() { outsb_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr_F36E() { outsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr16_F26F() { outsw_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr16_F26F() { outsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr16_F36F() { outsw_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr16_F36F() { outsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr32_F26F() { outsd_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr32_F26F() { outsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr32_F36F() { outsd_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr32_F36F() { outsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr16_70(imm8: i32) { jmpcc16(test_o(), imm8); }
#[no_mangle]
@ -3107,29 +3125,65 @@ pub unsafe fn instr32_7E(imm8: i32) { jmpcc32(test_le(), imm8); }
#[no_mangle]
pub unsafe fn instr32_7F(imm8: i32) { jmpcc32(!test_le(), imm8); }
#[no_mangle]
pub unsafe fn instr_F2A4() { movsb_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr_F2A4() { movsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr_F3A4() { movsb_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr_F3A4() { movsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr16_F2A5() { movsw_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr16_F2A5() { movsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr16_F3A5() { movsw_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr16_F3A5() { movsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr32_F2A5() { movsd_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr32_F2A5() { movsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr32_F3A5() { movsd_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr32_F3A5() { movsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr_F2A6() { cmpsb_rep(PREFIX_F2, is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr_F2A6() {
cmpsb_rep(
PREFIX_F2,
is_asize_32(),
return_on_pagefault!(get_seg_prefix(DS)),
);
}
#[no_mangle]
pub unsafe fn instr_F3A6() { cmpsb_rep(PREFIX_F3, is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr_F3A6() {
cmpsb_rep(
PREFIX_F3,
is_asize_32(),
return_on_pagefault!(get_seg_prefix(DS)),
);
}
#[no_mangle]
pub unsafe fn instr16_F2A7() { cmpsw_rep(PREFIX_F2, is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr16_F2A7() {
cmpsw_rep(
PREFIX_F2,
is_asize_32(),
return_on_pagefault!(get_seg_prefix(DS)),
);
}
#[no_mangle]
pub unsafe fn instr16_F3A7() { cmpsw_rep(PREFIX_F3, is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr16_F3A7() {
cmpsw_rep(
PREFIX_F3,
is_asize_32(),
return_on_pagefault!(get_seg_prefix(DS)),
);
}
#[no_mangle]
pub unsafe fn instr32_F2A7() { cmpsd_rep(PREFIX_F2, is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr32_F2A7() {
cmpsd_rep(
PREFIX_F2,
is_asize_32(),
return_on_pagefault!(get_seg_prefix(DS)),
);
}
#[no_mangle]
pub unsafe fn instr32_F3A7() { cmpsd_rep(PREFIX_F3, is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr32_F3A7() {
cmpsd_rep(
PREFIX_F3,
is_asize_32(),
return_on_pagefault!(get_seg_prefix(DS)),
);
}
#[no_mangle]
pub unsafe fn instr_F2AA() { stosb_rep(is_asize_32()); }
#[no_mangle]
@ -3143,17 +3197,17 @@ pub unsafe fn instr32_F2AB() { stosd_rep(is_asize_32()); }
#[no_mangle]
pub unsafe fn instr32_F3AB() { stosd_rep(is_asize_32()); }
#[no_mangle]
pub unsafe fn instr_F2AC() { lodsb_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr_F2AC() { lodsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr_F3AC() { lodsb_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr_F3AC() { lodsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr16_F2AD() { lodsw_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr16_F2AD() { lodsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr16_F3AD() { lodsw_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr16_F3AD() { lodsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr32_F2AD() { lodsd_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr32_F2AD() { lodsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr32_F3AD() { lodsd_rep(is_asize_32(), get_seg_prefix(DS)); }
pub unsafe fn instr32_F3AD() { lodsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
#[no_mangle]
pub unsafe fn instr_F2AE() { scasb_rep(PREFIX_F2, is_asize_32()); }
#[no_mangle]

View file

@ -4967,7 +4967,11 @@ pub unsafe fn maskmovq(r1: i32, r2: i32, addr: i32) {
}
#[no_mangle]
pub unsafe fn instr_0FF7_reg(r1: i32, r2: i32) {
maskmovq(r1, r2, get_seg_prefix(DS) + get_reg_asize(EDI))
maskmovq(
r1,
r2,
return_on_pagefault!(get_seg_prefix_ds(get_reg_asize(EDI))),
)
}
#[no_mangle]
@ -4996,7 +5000,11 @@ pub unsafe fn maskmovdqu(r1: i32, r2: i32, addr: i32) {
}
#[no_mangle]
pub unsafe fn instr_660FF7_reg(r1: i32, r2: i32) {
maskmovdqu(r1, r2, get_seg_prefix(DS) + get_reg_asize(EDI))
maskmovdqu(
r1,
r2,
return_on_pagefault!(get_seg_prefix_ds(get_reg_asize(EDI))),
)
}
#[no_mangle]
pub unsafe fn instr_0FF8(source: reg64, r: i32) {

View file

@ -6,81 +6,81 @@ pub unsafe fn resolve_modrm16(modrm_byte: i32) -> OrPageFault<i32> {
Ok(match modrm_byte {
0 | 8 | 16 | 24 | 32 | 40 | 48 | 56 => get_seg_prefix_ds(
*reg16.offset(BX as isize) as i32 + *reg16.offset(SI as isize) as i32 & 0xFFFF,
),
)?,
64 | 72 | 80 | 88 | 96 | 104 | 112 | 120 => get_seg_prefix_ds(
*reg16.offset(BX as isize) as i32 + *reg16.offset(SI as isize) as i32 + read_imm8s()?
& 0xFFFF,
),
)?,
128 | 136 | 144 | 152 | 160 | 168 | 176 | 184 => get_seg_prefix_ds(
*reg16.offset(BX as isize) as i32 + *reg16.offset(SI as isize) as i32 + read_imm16()?
& 0xFFFF,
),
)?,
1 | 9 | 17 | 25 | 33 | 41 | 49 | 57 => get_seg_prefix_ds(
*reg16.offset(BX as isize) as i32 + *reg16.offset(DI as isize) as i32 & 0xFFFF,
),
)?,
65 | 73 | 81 | 89 | 97 | 105 | 113 | 121 => get_seg_prefix_ds(
*reg16.offset(BX as isize) as i32 + *reg16.offset(DI as isize) as i32 + read_imm8s()?
& 0xFFFF,
),
)?,
129 | 137 | 145 | 153 | 161 | 169 | 177 | 185 => get_seg_prefix_ds(
*reg16.offset(BX as isize) as i32 + *reg16.offset(DI as isize) as i32 + read_imm16()?
& 0xFFFF,
),
)?,
2 | 10 | 18 | 26 | 34 | 42 | 50 | 58 => get_seg_prefix_ss(
*reg16.offset(BP as isize) as i32 + *reg16.offset(SI as isize) as i32 & 0xFFFF,
),
)?,
66 | 74 | 82 | 90 | 98 | 106 | 114 | 122 => get_seg_prefix_ss(
*reg16.offset(BP as isize) as i32 + *reg16.offset(SI as isize) as i32 + read_imm8s()?
& 0xFFFF,
),
)?,
130 | 138 | 146 | 154 | 162 | 170 | 178 | 186 => get_seg_prefix_ss(
*reg16.offset(BP as isize) as i32 + *reg16.offset(SI as isize) as i32 + read_imm16()?
& 0xFFFF,
),
)?,
3 | 11 | 19 | 27 | 35 | 43 | 51 | 59 => get_seg_prefix_ss(
*reg16.offset(BP as isize) as i32 + *reg16.offset(DI as isize) as i32 & 0xFFFF,
),
)?,
67 | 75 | 83 | 91 | 99 | 107 | 115 | 123 => get_seg_prefix_ss(
*reg16.offset(BP as isize) as i32 + *reg16.offset(DI as isize) as i32 + read_imm8s()?
& 0xFFFF,
),
)?,
131 | 139 | 147 | 155 | 163 | 171 | 179 | 187 => get_seg_prefix_ss(
*reg16.offset(BP as isize) as i32 + *reg16.offset(DI as isize) as i32 + read_imm16()?
& 0xFFFF,
),
)?,
4 | 12 | 20 | 28 | 36 | 44 | 52 | 60 => {
get_seg_prefix_ds(*reg16.offset(SI as isize) as i32 & 0xFFFF)
get_seg_prefix_ds(*reg16.offset(SI as isize) as i32 & 0xFFFF)?
},
68 | 76 | 84 | 92 | 100 | 108 | 116 | 124 => {
get_seg_prefix_ds(*reg16.offset(SI as isize) as i32 + read_imm8s()? & 0xFFFF)
get_seg_prefix_ds(*reg16.offset(SI as isize) as i32 + read_imm8s()? & 0xFFFF)?
},
132 | 140 | 148 | 156 | 164 | 172 | 180 | 188 => {
get_seg_prefix_ds(*reg16.offset(SI as isize) as i32 + read_imm16()? & 0xFFFF)
get_seg_prefix_ds(*reg16.offset(SI as isize) as i32 + read_imm16()? & 0xFFFF)?
},
5 | 13 | 21 | 29 | 37 | 45 | 53 | 61 => {
get_seg_prefix_ds(*reg16.offset(DI as isize) as i32 & 0xFFFF)
get_seg_prefix_ds(*reg16.offset(DI as isize) as i32 & 0xFFFF)?
},
69 | 77 | 85 | 93 | 101 | 109 | 117 | 125 => {
get_seg_prefix_ds(*reg16.offset(DI as isize) as i32 + read_imm8s()? & 0xFFFF)
get_seg_prefix_ds(*reg16.offset(DI as isize) as i32 + read_imm8s()? & 0xFFFF)?
},
133 | 141 | 149 | 157 | 165 | 173 | 181 | 189 => {
get_seg_prefix_ds(*reg16.offset(DI as isize) as i32 + read_imm16()? & 0xFFFF)
get_seg_prefix_ds(*reg16.offset(DI as isize) as i32 + read_imm16()? & 0xFFFF)?
},
6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 => get_seg_prefix_ds(read_imm16()?),
6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 => get_seg_prefix_ds(read_imm16()?)?,
70 | 78 | 86 | 94 | 102 | 110 | 118 | 126 => {
get_seg_prefix_ss(*reg16.offset(BP as isize) as i32 + read_imm8s()? & 0xFFFF)
get_seg_prefix_ss(*reg16.offset(BP as isize) as i32 + read_imm8s()? & 0xFFFF)?
},
134 | 142 | 150 | 158 | 166 | 174 | 182 | 190 => {
get_seg_prefix_ss(*reg16.offset(BP as isize) as i32 + read_imm16()? & 0xFFFF)
get_seg_prefix_ss(*reg16.offset(BP as isize) as i32 + read_imm16()? & 0xFFFF)?
},
7 | 15 | 23 | 31 | 39 | 47 | 55 | 63 => {
get_seg_prefix_ds(*reg16.offset(BX as isize) as i32 & 0xFFFF)
get_seg_prefix_ds(*reg16.offset(BX as isize) as i32 & 0xFFFF)?
},
71 | 79 | 87 | 95 | 103 | 111 | 119 | 127 => {
get_seg_prefix_ds(*reg16.offset(BX as isize) as i32 + read_imm8s()? & 0xFFFF)
get_seg_prefix_ds(*reg16.offset(BX as isize) as i32 + read_imm8s()? & 0xFFFF)?
},
135 | 143 | 151 | 159 | 167 | 175 | 183 | 191 => {
get_seg_prefix_ds(*reg16.offset(BX as isize) as i32 + read_imm16()? & 0xFFFF)
get_seg_prefix_ds(*reg16.offset(BX as isize) as i32 + read_imm16()? & 0xFFFF)?
},
_ => {
dbg_assert!(false);
@ -102,23 +102,23 @@ pub unsafe fn resolve_modrm32_(modrm_byte: i32) -> OrPageFault<i32> {
}
else if r as i32 == 5 {
if modrm_byte < 64 {
get_seg_prefix_ds(read_imm32s()?)
get_seg_prefix_ds(read_imm32s()?)?
}
else {
get_seg_prefix_ss(
*reg32.offset(EBP as isize)
+ if modrm_byte < 128 { read_imm8s()? } else { read_imm32s()? },
)
)?
}
}
else if modrm_byte < 64 {
get_seg_prefix_ds(*reg32.offset(r as isize))
get_seg_prefix_ds(*reg32.offset(r as isize))?
}
else {
get_seg_prefix_ds(
*reg32.offset(r as isize)
+ if modrm_byte < 128 { read_imm8s()? } else { read_imm32s()? },
)
)?
})
}
unsafe fn resolve_sib(mod_0: bool) -> OrPageFault<i32> {
@ -154,62 +154,62 @@ unsafe fn resolve_sib(mod_0: bool) -> OrPageFault<i32> {
s = (sib_byte as i32 >> 6 & 3) as u8;
offset = *reg32.offset(m as isize) << s as i32
}
Ok(get_seg_prefix(seg) + base + offset)
Ok(get_seg_prefix(seg)? + base + offset)
}
pub unsafe fn resolve_modrm32(modrm_byte: i32) -> OrPageFault<i32> {
Ok(match modrm_byte {
0 | 8 | 16 | 24 | 32 | 40 | 48 | 56 => get_seg_prefix_ds(*reg32.offset(EAX as isize)),
0 | 8 | 16 | 24 | 32 | 40 | 48 | 56 => get_seg_prefix_ds(*reg32.offset(EAX as isize))?,
64 | 72 | 80 | 88 | 96 | 104 | 112 | 120 => {
get_seg_prefix_ds(*reg32.offset(EAX as isize) + read_imm8s()?)
get_seg_prefix_ds(*reg32.offset(EAX as isize) + read_imm8s()?)?
},
128 | 136 | 144 | 152 | 160 | 168 | 176 | 184 => {
get_seg_prefix_ds(*reg32.offset(EAX as isize) + read_imm32s()?)
get_seg_prefix_ds(*reg32.offset(EAX as isize) + read_imm32s()?)?
},
1 | 9 | 17 | 25 | 33 | 41 | 49 | 57 => get_seg_prefix_ds(*reg32.offset(ECX as isize)),
1 | 9 | 17 | 25 | 33 | 41 | 49 | 57 => get_seg_prefix_ds(*reg32.offset(ECX as isize))?,
65 | 73 | 81 | 89 | 97 | 105 | 113 | 121 => {
get_seg_prefix_ds(*reg32.offset(ECX as isize) + read_imm8s()?)
get_seg_prefix_ds(*reg32.offset(ECX as isize) + read_imm8s()?)?
},
129 | 137 | 145 | 153 | 161 | 169 | 177 | 185 => {
get_seg_prefix_ds(*reg32.offset(ECX as isize) + read_imm32s()?)
get_seg_prefix_ds(*reg32.offset(ECX as isize) + read_imm32s()?)?
},
2 | 10 | 18 | 26 | 34 | 42 | 50 | 58 => get_seg_prefix_ds(*reg32.offset(EDX as isize)),
2 | 10 | 18 | 26 | 34 | 42 | 50 | 58 => get_seg_prefix_ds(*reg32.offset(EDX as isize))?,
66 | 74 | 82 | 90 | 98 | 106 | 114 | 122 => {
get_seg_prefix_ds(*reg32.offset(EDX as isize) + read_imm8s()?)
get_seg_prefix_ds(*reg32.offset(EDX as isize) + read_imm8s()?)?
},
130 | 138 | 146 | 154 | 162 | 170 | 178 | 186 => {
get_seg_prefix_ds(*reg32.offset(EDX as isize) + read_imm32s()?)
get_seg_prefix_ds(*reg32.offset(EDX as isize) + read_imm32s()?)?
},
3 | 11 | 19 | 27 | 35 | 43 | 51 | 59 => get_seg_prefix_ds(*reg32.offset(EBX as isize)),
3 | 11 | 19 | 27 | 35 | 43 | 51 | 59 => get_seg_prefix_ds(*reg32.offset(EBX as isize))?,
67 | 75 | 83 | 91 | 99 | 107 | 115 | 123 => {
get_seg_prefix_ds(*reg32.offset(EBX as isize) + read_imm8s()?)
get_seg_prefix_ds(*reg32.offset(EBX as isize) + read_imm8s()?)?
},
131 | 139 | 147 | 155 | 163 | 171 | 179 | 187 => {
get_seg_prefix_ds(*reg32.offset(EBX as isize) + read_imm32s()?)
get_seg_prefix_ds(*reg32.offset(EBX as isize) + read_imm32s()?)?
},
4 | 12 | 20 | 28 | 36 | 44 | 52 | 60 => resolve_sib(false)?,
68 | 76 | 84 | 92 | 100 | 108 | 116 | 124 => resolve_sib(true)? + read_imm8s()?,
132 | 140 | 148 | 156 | 164 | 172 | 180 | 188 => resolve_sib(true)? + read_imm32s()?,
5 | 13 | 21 | 29 | 37 | 45 | 53 | 61 => get_seg_prefix_ds(read_imm32s()?),
5 | 13 | 21 | 29 | 37 | 45 | 53 | 61 => get_seg_prefix_ds(read_imm32s()?)?,
69 | 77 | 85 | 93 | 101 | 109 | 117 | 125 => {
get_seg_prefix_ss(*reg32.offset(EBP as isize) + read_imm8s()?)
get_seg_prefix_ss(*reg32.offset(EBP as isize) + read_imm8s()?)?
},
133 | 141 | 149 | 157 | 165 | 173 | 181 | 189 => {
get_seg_prefix_ss(*reg32.offset(EBP as isize) + read_imm32s()?)
get_seg_prefix_ss(*reg32.offset(EBP as isize) + read_imm32s()?)?
},
6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 => get_seg_prefix_ds(*reg32.offset(ESI as isize)),
6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 => get_seg_prefix_ds(*reg32.offset(ESI as isize))?,
70 | 78 | 86 | 94 | 102 | 110 | 118 | 126 => {
get_seg_prefix_ds(*reg32.offset(ESI as isize) + read_imm8s()?)
get_seg_prefix_ds(*reg32.offset(ESI as isize) + read_imm8s()?)?
},
134 | 142 | 150 | 158 | 166 | 174 | 182 | 190 => {
get_seg_prefix_ds(*reg32.offset(ESI as isize) + read_imm32s()?)
get_seg_prefix_ds(*reg32.offset(ESI as isize) + read_imm32s()?)?
},
7 | 15 | 23 | 31 | 39 | 47 | 55 | 63 => get_seg_prefix_ds(*reg32.offset(EDI as isize)),
7 | 15 | 23 | 31 | 39 | 47 | 55 | 63 => get_seg_prefix_ds(*reg32.offset(EDI as isize))?,
71 | 79 | 87 | 95 | 103 | 111 | 119 | 127 => {
get_seg_prefix_ds(*reg32.offset(EDI as isize) + read_imm8s()?)
get_seg_prefix_ds(*reg32.offset(EDI as isize) + read_imm8s()?)?
},
135 | 143 | 151 | 159 | 167 | 175 | 183 | 191 => {
get_seg_prefix_ds(*reg32.offset(EDI as isize) + read_imm32s()?)
get_seg_prefix_ds(*reg32.offset(EDI as isize) + read_imm32s()?)?
},
_ => {
dbg_assert!(false);

View file

@ -50,7 +50,8 @@ pub unsafe fn string_get_cycle_count2(size: i32, addr1: i32, addr2: i32) -> i32
#[no_mangle]
pub unsafe fn movsb_rep(is_asize_32: bool, ds: i32) {
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
if count == 0 {
@ -108,7 +109,8 @@ pub unsafe fn movsb_rep(is_asize_32: bool, ds: i32) {
#[no_mangle]
pub unsafe fn movsb_no_rep(is_asize_32: bool, ds: i32) {
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
return_on_pagefault!(safe_write8(dest, return_on_pagefault!(safe_read8(src))));
add_reg_asize(is_asize_32, EDI, size);
@ -118,7 +120,8 @@ pub unsafe fn movsb_no_rep(is_asize_32: bool, ds: i32) {
pub unsafe fn movsw_rep(is_asize_32: bool, ds: i32) {
let diff;
let mut src: i32 = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
if count == 0 {
@ -179,7 +182,8 @@ pub unsafe fn movsw_rep(is_asize_32: bool, ds: i32) {
#[no_mangle]
pub unsafe fn movsw_no_rep(is_asize_32: bool, ds: i32) {
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
return_on_pagefault!(safe_write16(dest, return_on_pagefault!(safe_read16(src))));
add_reg_asize(is_asize_32, EDI, size);
@ -189,7 +193,8 @@ pub unsafe fn movsw_no_rep(is_asize_32: bool, ds: i32) {
pub unsafe fn movsd_rep(is_asize_32: bool, ds: i32) {
let diff;
let mut src: i32 = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
if count == 0 {
@ -271,7 +276,8 @@ pub unsafe fn movsd_rep(is_asize_32: bool, ds: i32) {
#[no_mangle]
pub unsafe fn movsd_no_rep(is_asize_32: bool, ds: i32) {
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
return_on_pagefault!(safe_write32(dest, return_on_pagefault!(safe_read32s(src))));
add_reg_asize(is_asize_32, EDI, size);
@ -280,7 +286,8 @@ pub unsafe fn movsd_no_rep(is_asize_32: bool, ds: i32) {
#[no_mangle]
pub unsafe fn cmpsb_rep(prefix_flag: i32, is_asize_32: bool, ds: i32) {
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut data_src;
let mut data_dest;
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
@ -325,7 +332,8 @@ pub unsafe fn cmpsb_rep(prefix_flag: i32, is_asize_32: bool, ds: i32) {
#[no_mangle]
pub unsafe fn cmpsb_no_rep(is_asize_32: bool, ds: i32) {
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let data_src;
let data_dest;
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
@ -339,7 +347,8 @@ pub unsafe fn cmpsb_no_rep(is_asize_32: bool, ds: i32) {
pub unsafe fn cmpsw_rep(prefix_flag: i32, is_asize_32: bool, ds: i32) {
let diff;
let mut src: i32 = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut data_src;
let mut data_dest;
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
@ -407,7 +416,8 @@ pub unsafe fn cmpsw_rep(prefix_flag: i32, is_asize_32: bool, ds: i32) {
#[no_mangle]
pub unsafe fn cmpsw_no_rep(is_asize_32: bool, ds: i32) {
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let data_src;
let data_dest;
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
@ -421,7 +431,8 @@ pub unsafe fn cmpsw_no_rep(is_asize_32: bool, ds: i32) {
pub unsafe fn cmpsd_rep(prefix_flag: i32, is_asize_32: bool, ds: i32) {
let diff;
let mut src: i32 = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut data_src;
let mut data_dest;
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
@ -489,7 +500,8 @@ pub unsafe fn cmpsd_rep(prefix_flag: i32, is_asize_32: bool, ds: i32) {
#[no_mangle]
pub unsafe fn cmpsd_no_rep(is_asize_32: bool, ds: i32) {
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let data_src;
let data_dest;
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
@ -502,7 +514,8 @@ pub unsafe fn cmpsd_no_rep(is_asize_32: bool, ds: i32) {
#[no_mangle]
pub unsafe fn stosb_rep(is_asize_32: bool) {
let data = *reg8.offset(AL as isize) as i32;
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
if count == 0 {
@ -556,7 +569,8 @@ pub unsafe fn stosb_rep(is_asize_32: bool) {
#[no_mangle]
pub unsafe fn stosb_no_rep(is_asize_32: bool) {
let data = *reg8.offset(AL as isize) as i32;
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
return_on_pagefault!(safe_write8(dest, data));
add_reg_asize(is_asize_32, EDI, size);
@ -565,7 +579,8 @@ pub unsafe fn stosb_no_rep(is_asize_32: bool) {
pub unsafe fn stosw_rep(is_asize_32: bool) {
let diff;
let data = *reg16.offset(AX as isize) as i32;
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
if count == 0 {
@ -621,7 +636,8 @@ pub unsafe fn stosw_rep(is_asize_32: bool) {
#[no_mangle]
pub unsafe fn stosw_no_rep(is_asize_32: bool) {
let data = *reg16.offset(AX as isize) as i32;
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
return_on_pagefault!(safe_write16(dest, data));
add_reg_asize(is_asize_32, EDI, size);
@ -630,7 +646,8 @@ pub unsafe fn stosw_no_rep(is_asize_32: bool) {
pub unsafe fn stosd_rep(is_asize_32: bool) {
let diff;
let data = *reg32.offset(EAX as isize);
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
if count == 0 {
@ -703,7 +720,8 @@ pub unsafe fn stosd_rep(is_asize_32: bool) {
#[no_mangle]
pub unsafe fn stosd_no_rep(is_asize_32: bool) {
let data = *reg32.offset(EAX as isize);
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
return_on_pagefault!(safe_write32(dest, data));
add_reg_asize(is_asize_32, EDI, size);
@ -825,7 +843,8 @@ pub unsafe fn lodsd_no_rep(is_asize_32: bool, ds: i32) {
}
#[no_mangle]
pub unsafe fn scasb_rep(prefix_flag: i32, is_asize_32: bool) {
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
let mut data_dest;
let data_src = *reg8.offset(AL as isize) as i32;
@ -865,7 +884,8 @@ pub unsafe fn scasb_rep(prefix_flag: i32, is_asize_32: bool) {
}
#[no_mangle]
pub unsafe fn scasb_no_rep(is_asize_32: bool) {
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
let data_dest;
let data_src = *reg8.offset(AL as isize) as i32;
@ -876,7 +896,8 @@ pub unsafe fn scasb_no_rep(is_asize_32: bool) {
#[no_mangle]
pub unsafe fn scasw_rep(prefix_flag: i32, is_asize_32: bool) {
let diff;
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
let mut data_dest;
let data_src = *reg16.offset(AL as isize) as i32;
@ -936,7 +957,8 @@ pub unsafe fn scasw_rep(prefix_flag: i32, is_asize_32: bool) {
}
#[no_mangle]
pub unsafe fn scasw_no_rep(is_asize_32: bool) {
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
let data_dest;
let data_src = *reg16.offset(AL as isize) as i32;
@ -947,7 +969,8 @@ pub unsafe fn scasw_no_rep(is_asize_32: bool) {
#[no_mangle]
pub unsafe fn scasd_rep(prefix_flag: i32, is_asize_32: bool) {
let diff;
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
let mut data_dest;
let data_src = *reg32.offset(EAX as isize);
@ -1007,7 +1030,8 @@ pub unsafe fn scasd_rep(prefix_flag: i32, is_asize_32: bool) {
}
#[no_mangle]
pub unsafe fn scasd_no_rep(is_asize_32: bool) {
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
let data_dest;
let data_src = *reg32.offset(EAX as isize);
@ -1022,7 +1046,8 @@ pub unsafe fn insb_rep(is_asize_32: bool) {
return;
}
else {
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
if count == 0 {
@ -1065,7 +1090,8 @@ pub unsafe fn insb_no_rep(is_asize_32: bool) {
return;
}
else {
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
return_on_pagefault!(writable_or_pagefault(dest, 1));
return_on_pagefault!(safe_write8(dest, io_port_read8(port)));
@ -1081,8 +1107,8 @@ pub unsafe fn insw_rep(is_asize_32: bool) {
return;
}
else {
let mut dest: i32 =
get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
if count == 0 {
@ -1145,7 +1171,8 @@ pub unsafe fn insw_no_rep(is_asize_32: bool) {
return;
}
else {
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
return_on_pagefault!(writable_or_pagefault(dest, 2));
return_on_pagefault!(safe_write16(dest, io_port_read16(port)));
@ -1161,8 +1188,8 @@ pub unsafe fn insd_rep(is_asize_32: bool) {
return;
}
else {
let mut dest: i32 =
get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
if count == 0 {
@ -1225,7 +1252,8 @@ pub unsafe fn insd_no_rep(is_asize_32: bool) {
return;
}
else {
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let dest = return_on_pagefault!(get_seg(ES))
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
return_on_pagefault!(writable_or_pagefault(dest, 4));
return_on_pagefault!(safe_write32(dest, io_port_read32(port)));