Skip to content

Commit

Permalink
Be aggressive about saving registers in the 16-bit bridge.
Browse files Browse the repository at this point in the history
Fixes a lot of stuff.  :)
  • Loading branch information
icculus committed Jun 14, 2018
1 parent cdaf533 commit a80afaa
Showing 1 changed file with 30 additions and 4 deletions.
34 changes: 30 additions & 4 deletions native/os2native16.h
Expand Up @@ -74,6 +74,12 @@

/* This is the original assembly code, for use with NASM.
USE16 ; start in 16-bit code where our 16-bit caller lands.
PUSH BX ; this might be overkill, but save off everything you can, just in case.
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
MOV CX, SP ; save off sp
JMP DWORD 0x7788:0x33332222 ; jmp into the 32-bit code segment (the next instruction!).
Expand All @@ -91,7 +97,7 @@ MOV AX, CX ; move the stack offset into the low word. Now %eax has the linear s
MOV CX, 0xABCD ; original linear stack segment from lx_loader's main().
MOV SS, CX
MOV ESP, EAX ; and the same stack pointer, but linear.
ADD EAX, 4 ; %eax now points to original function arguments on the stack.
ADD EAX, 16 ; %eax now points to original function arguments on the stack.
PUSH EBX ; save original ss:sp to stack.
PUSH DS ; save off the caller's data segment.
Expand Down Expand Up @@ -121,6 +127,14 @@ JMP WORD 0xAAAA:0xBBBB ; back into 16-bit land (the next instruction!).
USE16
MOV SS, CX
MOV SP, BX
POP BP ; restore all our overkill registers
POP DI
POP SI
POP DX
POP CX
POP BX
RETF 0x22 ; ...and back to the (far) caller, clearing the args (Pascal calling convention!) with retval in AX.
*/

Expand All @@ -129,6 +143,12 @@ RETF 0x22 ; ...and back to the (far) caller, clearing the args (Pascal calling
\
/* instructions are in Intel syntax here, not AT&T. */ \
/* USE16 */ \
*(ptr++) = 0x53; /* push bx */ \
*(ptr++) = 0x51; /* push cx */ \
*(ptr++) = 0x52; /* push dx */ \
*(ptr++) = 0x56; /* push si */ \
*(ptr++) = 0x57; /* push di */ \
*(ptr++) = 0x55; /* push bp */ \
*(ptr++) = 0x89; /* mov cx,sp... */ \
*(ptr++) = 0xE1; /* ...mov cx,sp */ \
*(ptr++) = 0x66; /* jmp dword 0x7788:0x33332222... */ \
Expand Down Expand Up @@ -167,9 +187,9 @@ RETF 0x22 ; ...and back to the (far) caller, clearing the args (Pascal calling
*(ptr++) = 0xD1; /* ...mov ss,ecx */ \
*(ptr++) = 0x89; /* mov esp,eax... */ \
*(ptr++) = 0xC4; /* ...mov esp,eax */ \
*(ptr++) = 0x83; /* add eax,byte +0x4... */ \
*(ptr++) = 0xC0; /* ...add eax,byte +0x4 */ \
*(ptr++) = 0x04; /* ...add eax,byte +0x4 */ \
*(ptr++) = 0x83; /* add eax,byte +0x10... */ \
*(ptr++) = 0xC0; /* ...add eax,byte +0x10 */ \
*(ptr++) = 0x10; /* ...add eax,byte +0x10 */ \
*(ptr++) = 0x53; /* push ebx */ \
*(ptr++) = 0x1E; /* push ds */ \
*(ptr++) = 0x06; /* push es */ \
Expand Down Expand Up @@ -214,6 +234,12 @@ RETF 0x22 ; ...and back to the (far) caller, clearing the args (Pascal calling
*(ptr++) = 0xD1; /* ...mov ss,cx */ \
*(ptr++) = 0x89; /* mov sp,bx... */ \
*(ptr++) = 0xDC; /* ...mov sp,bx */ \
*(ptr++) = 0x5D; /* pop bp */ \
*(ptr++) = 0x5F; /* pop di */ \
*(ptr++) = 0x5E; /* pop si */ \
*(ptr++) = 0x5A; /* pop dx */ \
*(ptr++) = 0x59; /* pop cx */ \
*(ptr++) = 0x5B; /* pop bx */ \
*(ptr++) = 0xCA; /* retf 0x22... */ \
const uint16 argbytecount = argbytes; \
memcpy(ptr, &argbytecount, 2); ptr += 2; \
Expand Down

0 comments on commit a80afaa

Please sign in to comment.