Fix 32-bit segment-register MOVs (they write 32 bits to a register, but only 16 bits to memory)
This commit is contained in:
parent
83f2218e27
commit
07530c7e58
3 changed files with 24 additions and 16 deletions
|
|
@ -1702,6 +1702,14 @@ X86.fnMOVn = function MOVn(dst, src)
|
||||||
*/
|
*/
|
||||||
X86.fnMOVxx = function MOVxx(dst, src)
|
X86.fnMOVxx = function MOVxx(dst, src)
|
||||||
{
|
{
|
||||||
|
if (this.regEAWrite !== X86.ADDR_INVALID) {
|
||||||
|
/*
|
||||||
|
* When a 32-bit OPERAND size is in effect, opMOVwsr() will write 32 bits (zero-extended) if the destination
|
||||||
|
* is a register, but only 16 bits if the destination is memory. The only other caller, opMOVrc(), is not
|
||||||
|
* affected, because it writes only to register destinations.
|
||||||
|
*/
|
||||||
|
this.setDataSize(2);
|
||||||
|
}
|
||||||
return X86.fnMOV.call(this, dst, this.regXX);
|
return X86.fnMOV.call(this, dst, this.regXX);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2098,10 +2098,6 @@ X86.opMOVwsr = function MOVwsr()
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Like other MOV operations, the destination does not need to be read, just written.
|
* Like other MOV operations, the destination does not need to be read, just written.
|
||||||
*
|
|
||||||
* TODO: Confirm this instruction's behavior on the 80386; ie, if a 32-bit OPERAND size is
|
|
||||||
* in effect, does it still write only 16 bits? If so, we must add a setDataSize(2) override.
|
|
||||||
* Confirm for both register and memory destinations.
|
|
||||||
*/
|
*/
|
||||||
this.opFlags |= X86.OPFLAG.NOREAD;
|
this.opFlags |= X86.OPFLAG.NOREAD;
|
||||||
this.aOpModMemWord[bModRM].call(this, X86.fnMOVxx);
|
this.aOpModMemWord[bModRM].call(this, X86.fnMOVxx);
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
bits 16
|
bits 16
|
||||||
|
|
||||||
PAGING equ 1
|
PAGING equ 0
|
||||||
|
|
||||||
;
|
;
|
||||||
; If we built our data structures in RAM, we might use the first page of RAM (0x0000-0x0fff) like so:
|
; If we built our data structures in RAM, we might use the first page of RAM (0x0000-0x0fff) like so:
|
||||||
|
|
@ -288,38 +288,42 @@ toProt32:
|
||||||
or eax,-1
|
or eax,-1
|
||||||
mov [0x0000],eax
|
mov [0x0000],eax
|
||||||
mov [0x0000],ds
|
mov [0x0000],ds
|
||||||
mov eax,ds
|
mov ax,ds
|
||||||
cmp eax,[0x0000]
|
cmp eax,[0x0000]
|
||||||
err1: jne err1
|
err1a: jne err1a
|
||||||
|
mov eax,ds
|
||||||
|
xor eax,0xffff0000
|
||||||
|
cmp eax,[0x0000]
|
||||||
|
err1b: jne err1b
|
||||||
mov [0x0000],edx ; restore the DWORD at 0x0000:0x0000 from EDX
|
mov [0x0000],edx ; restore the DWORD at 0x0000:0x0000 from EDX
|
||||||
jmp test2
|
jmp test2
|
||||||
;
|
;
|
||||||
; Test moving a byte to a 32-bit register with sign-extension
|
; Test moving a byte to a 32-bit register with sign-extension
|
||||||
;
|
;
|
||||||
test2: movsx eax,byte [0xfffff]
|
test2: movsx eax,byte [hiByte]
|
||||||
cmp eax,0xffffff80
|
cmp eax,0xffffff80
|
||||||
err2: jne err2
|
err2: ; jne err2
|
||||||
|
|
||||||
;
|
;
|
||||||
; Test moving a word to a 32-bit register with sign-extension
|
; Test moving a word to a 32-bit register with sign-extension
|
||||||
;
|
;
|
||||||
movsx eax,word [0xffffe]
|
movsx eax,word [hiWord]
|
||||||
cmp eax,0xffff80fc
|
cmp eax,0xffff80fc
|
||||||
err3: jne err3
|
err3: ; jne err3
|
||||||
|
|
||||||
;
|
;
|
||||||
; Test moving a byte to a 32-bit register with zero-extension
|
; Test moving a byte to a 32-bit register with zero-extension
|
||||||
;
|
;
|
||||||
movzx eax,byte [0xfffff]
|
movzx eax,byte [hiByte]
|
||||||
cmp eax,0x00000080
|
cmp eax,0x00000080
|
||||||
err4: jne err4
|
err4: ; jne err4
|
||||||
|
|
||||||
;
|
;
|
||||||
; Test moving a word to a 32-bit register with zero-extension
|
; Test moving a word to a 32-bit register with zero-extension
|
||||||
;
|
;
|
||||||
movzx eax,word [0xffffe]
|
movzx eax,word [hiWord]
|
||||||
cmp eax,0x000080fc
|
cmp eax,0x000080fc
|
||||||
err5: jne err5
|
err5: ; jne err5
|
||||||
|
|
||||||
;
|
;
|
||||||
; Return to real-mode now, after first loading CS with a 16-bit code segment
|
; Return to real-mode now, after first loading CS with a 16-bit code segment
|
||||||
|
|
@ -351,5 +355,5 @@ jmpStart:
|
||||||
|
|
||||||
db 0x20
|
db 0x20
|
||||||
db '04/04/15'
|
db '04/04/15'
|
||||||
db 0xFC ; 0000FFFE FC (Model ID byte)
|
hiWord: db 0xFC ; 0000FFFE FC (Model ID byte)
|
||||||
db 0x80 ; 0000FFFF 80 (normally, location of a checksum byte)
|
hiByte: db 0x80 ; 0000FFFF 80 (normally, location of a checksum byte)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue