News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Compile mixed 16 & 32 bit code

Started by guga50, November 12, 2007, 07:03:30 PM

Previous topic - Next topic

guga50

Can I use masm32 to compile and link mixed code that contains both 16 and 32 bit instructions?
Something like this (it will be a loader for a boot sector):

ORG 0x7C00
use16

start:
    jmp init
GDT:
dd  0,0
db  0FFh, 0FFh, 00h, 00h, 00h, 10011010b, 11001111b, 00
db  0FFh, 0FFh, 00h, 00h, 00h, 10010010b, 11001111b, 00
db  0FFh, 0FFh, 00h, 80h, 0Bh, 10010010b, 01000000b, 00
db  0FFh, 0FFh, 00h, 00h, 00h, 10011010b, 00000000b, 00

    GDT_size equ $-GDT
    GDTR dw GDT_size-1
dd GDT

; Interrupt Descriptor Table
IDT:
dd 0,0 ; 0
dw syscall_handler, 08h, 1000111000000000b, 0 ; 1
dd 0,0 ; 2
...
dd 0,0 ; 12
dw exGP_handler, 08h, 1000111000000000b, 0   ; 13  #GP
dd 0,0 ; 14
...
dd 0,0 ; 31
dw int8_handler, 08h, 1000111000000000b, 0   ; IRQ 0 - system timer
dw int9_handler, 08h, 1000111000000000b, 0   ; IRQ 1 - keyboard

    IDT_size equ $-IDT
    IDTR dw IDT_size-1
dd IDT
    REAL_IDTR dw 3FFh
dd 0

init:
    ; clear screen
    mov  ax,3
    int  10h
    mov  ax, cs
    mov  ds, ax
    mov  es, ax
    mov  ss, ax
    mov  sp, start
    mov  bp, sp

    ; load sectors into memory
    mov  ah, 2 ; AH = Function                          : Read sectors
    mov  al, 10 ; AL = Number of sectors to read (1-128) : 10
    xor  ch, ch ; CH = Cylinder number (0-1023)          : 0
    mov  cl, 2 ; CL = Sector number (1-17)              : 2
    xor  dx, dx ; DH = Head number (0-15)                : 0
; DL = Drive number (0-A:, 1-B:)         : 0 (A:)
    mov  bx, start + 512
    int  13h
    jnc  continue_loading

    jmp display_read_error
read_error db 'R',7, 'e',7, 'a',7, 'd',7, ' ',7, 'e',7, 'r',7, 'r',7, 'o',7, 'r',7
read_err_l dw $-read_error
display_read_error:
    mov  ax, 0B800h
    mov  es, ax
    xor  di, di
    mov  si, read_error
    mov  cx, word [read_err_l]
    rep  movsb
    jmp  $

ends: rb 510-(ends-start)
db 055h, 0aah

continue_loading:

    ; open A20
    in al, 92h
    or al, 2
    out  92h, al

    ; disable all interruption
    cli
    in al, 70h
    or al, 80h
    out  70h, al  ; disable NMI

    ; load GDTR
    lgdt fword [GDTR]

    ; load IDTR
    lidt fword [IDTR]

    ; switch to PM
    mov  eax, cr0
    or al, 1
    mov  cr0, eax

    jmp  00001000b:PROTECTED_ENTRY

use32
PROTECTED_ENTRY:
    mov  ax, 00010000b ; DATA
    mov  ds, ax
    mov  ss, ax
    mov  ax, 00011000b ; VIDEO
    mov  es, ax
    mov  dx, 0FFFFh
    mov  bx, 2820h
    call redirect_IRQ

    in al, 70h
    and  al, 7Fh
    out  70h, al
    sti

    mov  esi, string
    int 1

    mov  dword [cursor], 160

    jmp  $

; IRQ 0

int8_handler:
    inc  byte [es:0]
    jmp  int_EOI

; IRQ 1

int9_handler:
    push ax
    push edi
    xor  ax, ax

    in al, 060h

    dec  al
    jnz _continue_handling

    mov  ax, 3
    push 10h
    call REAL_MODE_SWITCH_SERVICE

    jmp Ack

_continue_handling:
   
    mov  ah, al
    and  ah, 80h
    jnz clear_request
 
    and  al, 7Fh
    push edi
    mov  edi, ascii
    add  di, ax
    mov  al, [edi]
    pop  edi

    mov  edi, dword [cursor]
    shl  edi, 1
    mov  byte [es:edi], al
    inc  dword [cursor]

   Ack:
    in al, 061h
    or al, 80
    out  061h, al
    xor  al, 80
    out  061h, al

clear_request:
    pop  edi
    pop  ax
    jmp  int_EOI

int_EOI:
   
    push ax
    mov  al, 20h
    out  020h, al
    out  0a0h, al
    pop  ax
    iretd

;  #GP Exception handler

exGP_handler:
    pop  eax ;
    mov  esi, gp
    int  1
    iretd

syscall_handler:
    pushad
  _puts:
    lodsb
    mov  edi, dword [cursor]
    mov  [es:edi*2], al
    inc  dword [cursor]
    test al, al
    jnz  _puts
    popad
    iretd

use32
old_ax dw ?
old_cl db ?
REAL_MODE_SWITCH_SERVICE:
    mov  [old_cl], cl
    mov  [old_ax], ax

    mov  cl, [esp+4]

    pushfd
    cli
    in al, 70h
    or al, 80h
    out  70h, al

    lidt fword [REAL_IDTR]

    jmp  00100000b:__CONT

use16
    __CONT:

    mov  eax, cr0
    and  al, 0FEh
    mov  cr0, eax
    jmp  0:REAL_ENTRY

REAL_ENTRY:
    mov  ax, cs
    mov  ds, ax
    mov  ss, ax
    mov  es, ax

    in al, 70h
    and  al, 7Fh
    out  70h, al
    sti

   ... and so on. (Excuse me for such a long message)


MichaelW

I added code tags to your post to make the code a little easier to read.

You can assemble and link similar code, but not the exact code you posted. Agner Fog has several test programs that switch to PM and IIRC back to RM, but not on the fly as you appear to be doing in your code, available here:

http://www.agner.org/optimize/#testp

eschew obfuscation