Real mode loader, OS program halts.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
chendsh

Real mode loader, OS program halts.

Post by chendsh »

I have a boot sector program which load a program
to 0x1000:0000. Certainly the program is in real mode.
And then I write a program using assembly and C.
I compiled them using NASM and DGJPP and linked the object
files using ld, which is another program in DJGPP.
When loaded , the computer just hangs there..
I need your kind help
the C part is simple:
void main()
{
prntenh("pppppp %l \n",4999999);
while(1)
;
}

and the assembly part is just like printf function is C.
it is too long ,sorry:
[BITS 32]
global _prntenh
section .text
_prntenh: ;enhanced prnt-- support integer output
push bp; ;and long integer output
mov bp,sp;

mov ax,0
push ax ;counter for integers ---->[bp-2]
push ax ;counter for long integers ----->[bp-4]

mov di,[ss:bp+4]

outputenh:

mov al, [per]
scasb
jz output_num ;replace mark with the parameter
mov al,[es:di-1]
cmp al, 0 ;end of the string ?
je near outendenh ;short jump is out of range, so use near here
;though Ive changed it to short jmp again.
mov al, [es:di-1]
mov ah,0eh
mov bx,07h
int 10h
jmp outputenh
output_num:


mov al, [mark1]
cmp [es:di] ,al ;%d ?
jne _long_int ;long integer

lea ax, [ss:bp-2] ;integer
push ax
lea ax, [ss:bp-4]
push ax
lea ax, [ss:bp+6] ;begin addr of the integer or long integer
push ax

call _intnum
add sp, 0x6
inc di
jmp outputenh

_long_int:

lea ax, [ss:bp-2] ;integer
push ax
lea ax, [ss:bp-4]
push ax
lea ax, [ss:bp+6] ;begin addr of the integer or long integer
push ax

call _lintnum
add sp, 0x6
inc di
jmp outputenh

outendenh:
mov sp,bp
pop bp
retn

_intnum:
push bp
mov bp, sp

mov si, [ss:bp+8] ;addr of Numbers of integers, use** SI **concerning stack
mov ax, [si] ;only SI is legal
mov si, [ss:bp+6] ;addr of Numbers of long integers
mov bx, [si]

shl ax, 1
shl bx, 2
add ax, bx ;bytes should move on stack to the next para

;;;; mov si, ax ; get the count,***only SI is legal**** concerning stack

;;;; mov ax, [ss:bp+si+6] ;get the proper para

mov si, [ss:bp+4] ;addr of the integer or long integer to be ouput
add si, ax
mov ax, [si]
mov dx, 0x0 ;in case of quotient being larger than FF

mov si, [ss:bp+8] ;one more integer
mov bx, [si]
inc bx
mov [si], bx

push di ;save di in case of change by div

mov cx,0h
chg2dec:
mov bx, 0xa
div bx
mov bx, dx
push bx ;save remainder in the stack
inc cx
cmp ax, 0h
jz dec_num
mov dx, 0x0 ;process the quotient again
jmp chg2dec
dec_num:
pop ax ;get the remainder stored in the stack
and ax, 0x0f
add al, 0x30
mov ah,0eh
mov bx,07h
int 10h
loop dec_num

pop di


mov sp, bp
pop bp
retn

_lintnum: ;when the parameter is long integer
push bp
mov bp, sp

mov si, [ss:bp+8] ;addr of Numbers of integers, use** SI **concerning stack
mov ax, [si] ;only SI is legal
mov si, [ss:bp+6] ;addr of Numbers of long integers
mov bx, [si]

shl ax, 1
shl bx, 2
add ax, bx ;bytes should move on stack to the next para

;;;; mov si, ax ; get the count,***only SI is legal**** concerning stack

;;;; mov ax, [ss:bp+si+6] ;get the proper para

mov si, [ss:bp+4] ;addr of the integer or long integer to be ouput
add si, ax
mov eax, [si] ;long integer ---32 bits
mov edx, 0x0
;;; mov edx, eax
;;; shr edx, 16 ;save the num in dx:ax

mov si, [ss:bp+6] ;one more long integer
mov bx, [si]
inc bx
mov [si], bx

push di ;save di in case of change by div

mov cx,0h
lchg2dec:
mov ebx, 0xa
div ebx
mov bx, dx
push bx ;save remainder in the stack
inc cx
cmp eax, 0h
jz ldec_num
mov edx, 0h ;process the quotient again
jmp lchg2dec
ldec_num:
pop ax ;get the remainder stored in the stack
and ax, 0x0f
add al, 0x30
mov ah,0eh
mov bx,07h
int 10h
loop ldec_num

pop di


mov sp, bp
pop bp
retn


;SEGMENT _data PUBLIC CLASS=data
;segment data
per: db '%' ;replace mark in the format
mark1: db 'd'
Schol-R-LEA

RE:Real mode loader, OS program halts.

Post by Schol-R-LEA »

The immediate problem is, gcc doesn't generate
real-mode code; even if it did nothing but call a
real-mode function (which 'printenh()' isn't, as
you have NASM generating p-mode code as well), as
the function calls are themselves 32-bit code
anyway.

For this to run, you'd need to switch into
protected mode first, or alternately, use a real-
mode C compiler such as lcc as use [bits 16] in
the NASM code.
Post Reply