Search code examples
assemblynasmx86-16bootloaderbios

8086 not printing first character printing nulls instead


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

Solution

  • 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