Real mode loader, OS program halts.
Posted: Sun Apr 07, 2002 11:00 pm
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'
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'