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
The fastest solution is to add leading space characters to your string.
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.
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
And welcome to the forum, ewok.
Gunther
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
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
(http://www.c-jump.com/CIS77/asm_images/gp_registers.jpg)
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