News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

bootloader

Started by ewok, July 21, 2014, 04:56:24 AM

Previous topic - Next topic

ewok

Hello,
i've took a NASM code example and fixed it for MASM32, here it is:
code segment use16
assume cs:code
org 7c00h

start:
; Main program
main: ; Label for the start of the main program

mov ax,0000h ; Setup the Data Segment register
; Location of data is DS:Offset
mov ds,ax ; This can not be loaded directly it has to be in two steps.
; 'mov ds, 0000h' will NOT work due to limitations on the CPU

mov si,offset HelloWorld ; Load the string into position for the procedure.
call PutStr ; Call/start the procedure

jmp $ ; Never ending loop

; Procedures
PutStr: ; Procedure label/start
; Set up the registers for the interrupt call
mov ah,0Eh ; The function to display a chacter (teletype)
mov bh,00h ; Page number
mov bl,07h ; Normal text attribute

nextchar: ; Internal label (needed to loop round for the next character)
lodsb ; I think of this as LOaD String Block
; (Not sure if thats the real meaning though)
; Loads [SI] into AL and increases SI by one
; Check for end of string '0'
or al,al ; Sets the zero flag if al = 0
; (OR outputs 0's where there is a zero bit in the register)
jz return ; If the zero flag has been set go to the end of the procedure.
; Zero flag gets set when an instruction returns 0 as the answer.
int 10h ; Run the BIOS video interrupt
jmp nextchar ; Loop back round to the top
return: ; Label at the end to jump to when complete
ret ; Return to main program

; Data
HelloWorld db 'Hello World',13,10,0

db 510-($-start) dup(0)  ; Fill the rest of the sector with zero's
dw 0AA55h ; Add the boot loader signature to the end

code ends
end start

Did someone know how can i 'center' the hello world on the screen ?

Regards

Vortex

The fastest solution is to add leading space characters to your string.

KeepingRealBusy

ewok

Because SI is a pointer register. You need to load it with a pointer to the string:


mov si,OFFSET HelloWorld


If "HellowWorld" was a parameter to a function call, then you would need:


mov si,ADDRESS HelloWorld


To center the data you need to get the width of the screen less the length of the string, divide by 2, then print a string of blank characters before printing the message. Cheat, create a string of blanks (without the null terminator) immediately in front of the desired string, then pass the offset of the string less the half centering size.

Dave.

dedndave

the function you want is INT 10h, AH=2
;AH=2, BH = Page Number, DH = Row, DL = Column
    mov     bh,0
    mov     dx,23h
    mov     ah,2
    int     10h


it should be smaller than 35 spaces   :P

you can calculate, as Dave suggested.....
;AH=2, BH = Page Number, DH = Row, DL = Column
    mov     bh,0
    mov     dx,(80-sizeof HelloWorld-3)/2   ;-3 to ignore CR/LF/null
    mov     ah,2
    int     10h

Gunther

And welcome to the forum, ewok.

Gunther
You have to know the facts before you can distort them.

ewok

Thanks for the heads-up guys, and thanks Gunther :)
@dedndave, when i put you code looks like i'm having difficulty (that compile fine but when i boot, i've no text printed, at least seem AH=2 is the problem)
If dl is for column what are dx for ? he have the same role as dl ?
Also, there is a standard resolution for the height on dh ? (like 80?)

Regards

dedndave

function AH=2 sets the cursor position - it does not display any text
so - you want to set the position, then display the text

DL, DH, DX, EDX are all different ways to access the same register
EDX is a 32-bit register
DX is the lower 16 bits (word) of that same register
the High and Low bytes of DX may be accessed via DH and DL
EAX, EBX, and ECX are similar

so - we set the column in DL, and the row in DH to 0 - both by setting DX
normally, there are 80x25 char cells - unless it's set up to boot in 40x25 mode
as i recall, the original PC's and XT's had a DIP switch setting for startup mode
that way, if the user had a TV connected to the CGA composite output, it was legible


dedndave

this loop is a bit questionable
the reason i say that is - some BIOS may not preserve the contents of AX and BX across the call

PutStr: ; Procedure label/start
; Set up the registers for the interrupt call
mov ah,0Eh ; The function to display a chacter (teletype)
mov bh,00h ; Page number
mov bl,07h ; Normal text attribute

nextchar: ; Internal label (needed to loop round for the next character)
lodsb ; I think of this as LOaD String Block
; (Not sure if thats the real meaning though)
; Loads [SI] into AL and increases SI by one
; Check for end of string '0'
or al,al ; Sets the zero flag if al = 0
; (OR outputs 0's where there is a zero bit in the register)
jz return ; If the zero flag has been set go to the end of the procedure.
; Zero flag gets set when an instruction returns 0 as the answer.
int 10h ; Run the BIOS video interrupt
jmp nextchar


a better loop might be...

ShowChar:
    mov     bx,7
    mov     ah,0Eh
    int     10h

PutStr:
    lodsb
    or      al,al
    jnz     ShowChar

notice that loop entry is still PutStr   :t