There is an error in this code. The print_string doesnt print to the screen after pointing to the string, it only prints if the line in the code mov bx,8000h
is removed and the two lines after it, but then i cant write alot of bytes to ram the whole thing crashes after calling alloc and incrementing the basepointer like 20 times. what should i do, how do I get to write the string and make it not crash after writing like 20 bytes
[bits 16]
[org 0x7c00]
SEAM_STD_BUFFER equ 0
SEAM_STD_LIMIT equ 255
xor ax,ax
mov bx,ax
mov bx,cx
mov dx,0
mov ds,bx
mov es,bx
mov bp,0
mov sp,bp
mov ss,bp
mov bx,8000h
mov sp,bx
mov ss,bx
mov bp,0
jmp _start
_start:
call clear
.repeat:
mov bp, OS_USERNAME_DESCRIPT
call print_string
call Set_BasePointer_std
call read_string_show
jmp .repeat
Set_BasePointer_std:
mov bp,SEAM_STD_BUFFER
ret
read_char_show:;() returns al
call read_char
cmp al,8
je .back
call print
ret
.back:
cmp bp,SEAM_STD_BUFFER
je .done
call print
.done:
mov al,0
ret
read_string: ; (ptr bp place to allocate string)
call read_char
cmp al,13
je .done
call alloc
inc bp
cmp bp,SEAM_STD_LIMIT
jge .resetbp
jmp read_string
.done:
mov al,0
call alloc
ret
.resetbp:
call Set_BasePointer_std
jmp read_string
read_string_show: ; (ptr bp place to allocate string)
call read_char_show
cmp al,0
je read_string_show
cmp al,13
je .done
cmp al,8;;NOT GOOD ENOUGH
je .skip;;NOT GOOD ENOUGH
call alloc
inc bp
.skip:;;NOT GOOD ENOUGH
cmp bp,SEAM_STD_LIMIT
jge .resetbp
jmp read_string_show
.resetbp:
call Set_BasePointer_std
jmp read_string
.done:
mov al,0
call alloc
call next_line
ret
read_char: ;() returns al
mov ax,0x00
int 0x16
ret
clear:; ()
mov ah,0
mov al,3
int 0x10
ret
free:;(bp ptr at place start to free, ax at end )
mov [bp],byte 0
cmp bp,ax
je .done
inc bp
jmp free
.done:
ret
dalloc:; (ptr bp)
mov al,[bp]
ret
alloc: ;(bp place to allocate,al byte value)
mov [bp], al
ret
clear_line:
mov dh,0
call clear
ret
next_line:
mov ah,2
mov dl,0
inc dh
cmp dh ,25
jge clear_line
int 10h
ret
previous_line:
dec dh
mov ah,2
mov dl,0
int 10h
ret
next_char:; finish
string_compare:;finish
print: ; (al Character to print, bl color)
mov ah,0x0E
int 10h
ret
print_string: ;(ptr bp Place of string start)
call dalloc
cmp al,0
je .done
call print
inc bp
jmp print_string
.done:
ret
OS_WELCOME db 'What is giong on',0
OS_USERNAME_DESCRIPT db 'Username:'
times (510 - ($-$$)) db 0x00
dw 0xAA55
xor ax,ax mov bx,ax mov bx,cx <-- Here CX goes to BX mov dx,0 mov ds,bx <-- Here (via BX) CX goes to DS mov es,bx <-- Here (via BX) CX goes to ES
You don't setup the DS
and ES
segment registers correctly!
You've stored the value of CX
in them but CX
never got initialized with any useful value .
mov bp,0 mov sp,bp mov ss,bp mov bx,8000h mov sp,bx mov ss,bx
There's alot wrong with how you setup the stack. Doing it twice can't help much! Also when setting up the stackpointer always first assign SS
and immediately after assign SP
. The order is important.
For the actual value to put in SS
, frankly you got no choice. (Technically you have but let's not complicate things...) Given that you want to use BP
to point at your strings and that the whole program gets encoded with an ORG 0x7C00
the only correct value to put in SS
is zero.
I suggest you write:
xor ax, ax
mov ss, ax
mov sp, 0x7C00
This will put the stack just below your bootloader program, a safe place.
And because DS
and ES
also need a good initialization, make the whole thing:
xor ax, ax
mov ss, ax
mov sp, 0x7C00
mov ds, ax
mov es, ax
print: ; (al Character to print, bl color) mov ah,0x0E int 10h ret
This print routine still needs that you say to which display page the BIOS teletype function should write. The selection is done via the BH
register.
print:
mov bh, 0
mov ah, 0x0E
int 10h
ret
In order to verify that the printing works, you could make the program wait for a key:
_start:
call clear
.repeat:
mov bp, OS_USERNAME_DESCRIPT
call print_string
mov ah, 00h ;Wait for a key
int 16h ;Wait for a key
Once you're confident that this part of the code works fine, you just remove these 2 lines.
OS_USERNAME_DESCRIPT db 'Username:' times (510 - ($-$$)) db 0x00
Do terminate the string with an explicit zero. Don't rely on the following padding that happens to use zeroes.
In future:
My answer complements the answer given by Sep Roland that solved the matter of printing (and more).
It deals with the fact that the program keeps crashing after a number of characters have been inputted.
The problem lies in this line:
SEAM_STD_BUFFER equ 0
and its companion:
mov bp,SEAM_STD_BUFFER
Because the stack segment is now correctly positioned at 0, you should no longer store your characters starting at bp=0
. You do this in the alloc code mov [bp], al
.
You can store it in lots of other places but a good one would be directly behind the bootloader.
SEAM_STD_BUFFER equ 0x7E00
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.