Author Topic: bootloader  (Read 2435 times)

ewok

  • Regular Member
  • *
  • Posts: 5
bootloader
« on: July 21, 2014, 04:56:24 AM »
Hello,
i've took a NASM code example and fixed it for MASM32, here it is:
Code: [Select]
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

  • Member
  • *****
  • Posts: 1703
Re: bootloader
« Reply #1 on: July 21, 2014, 05:14:52 AM »
The fastest solution is to add leading space characters to your string.

KeepingRealBusy

  • Member
  • ***
  • Posts: 426
Re: bootloader
« Reply #2 on: July 21, 2014, 05:18:15 AM »
ewok

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

Code: [Select]
mov si,OFFSET HelloWorld

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

Code: [Select]
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

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: bootloader
« Reply #3 on: July 21, 2014, 05:39:55 AM »
the function you want is INT 10h, AH=2
Code: [Select]
;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.....
Code: [Select]
;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

  • Member
  • *****
  • Posts: 3515
  • Forgive your enemies, but never forget their names
Re: bootloader
« Reply #4 on: July 21, 2014, 08:37:30 AM »
And welcome to the forum, ewok.

Gunther
Get your facts first, and then you can distort them.

ewok

  • Regular Member
  • *
  • Posts: 5
Re: bootloader
« Reply #5 on: July 21, 2014, 10:59:07 AM »
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

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: bootloader
« Reply #6 on: July 21, 2014, 12:26:55 PM »
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

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: bootloader
« Reply #7 on: July 21, 2014, 12:35:09 PM »
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

Code: [Select]
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...

Code: [Select]
ShowChar:
    mov     bx,7
    mov     ah,0Eh
    int     10h

PutStr:
    lodsb
    or      al,al
    jnz     ShowChar
notice that loop entry is still PutStr   :t