I am following a tutorial to write a hello world bootloader in assembly and I am using the NASM assembler for an x-86 machine. This is the code I am using :
[BITS 16] ;Tells the assembler that its a 16 bit code
[ORG 0x7C00] ;Origin, tell the assembler that where the code will
;be in memory after it is been loaded
MOV SI, HelloString ;Store string pointer to SI
CALL PrintString ;Call print string procedure
JMP $ ;Infinite loop, hang it here.
PrintCharacter: ;Procedure to print character on screen
;Assume that ASCII value is in register AL
MOV AH, 0x0E ;Tell BIOS that we need to print one charater on screen.
MOV BH, 0x00 ;Page no.
MOV BL, 0x07 ;Text attribute 0x07 is lightgrey font on black background
INT 0x10 ;Call video interrupt
RET ;Return to calling procedure
PrintString: ;Procedure to print string on screen
;Assume that string starting pointer is in register SI
next_character: ;Lable to fetch next character from string
MOV AL, [SI] ;Get a byte from string and store in AL register
INC SI ;Increment SI pointer
OR AL, AL ;Check if value in AL is zero (end of string)
JZ exit_function ;If end then return
CALL PrintCharacter ;Else print the character which is in AL register
JMP next_character ;Fetch next character from string
exit_function: ;End label
RET ;Return from procedure
;Data
HelloString db 'Hello World', 0 ;HelloWorld string ending with 0
TIMES 510 - ($ - $$) db 0 ;Fill the rest of sector with 0
DW 0xAA55 ;Add boot signature at the end of bootloader
I have some difficulty understanding how I can place the complete 'Hello World ' string into one byte using the db command. As I understand it , db stands for define byte and it places the said byte directly in the executable , but surely 'Hello World' is larger than a byte. What am I missing here ?
To declare a string constant you can use the EQU or TEXTEQU directive. Both are declared before the data segment in the global scope. Then you can go on to use your named variable in the rest of the code. The TEXTEQU can be a bit trickier.
DB - Define Byte. 8 bits. DW - Define Word. Generally 2 bytes on a typical x86 32-bit system.
msg is a global variable pointing to the string that follows - the db means data byte , indicating that the assembler should just emit the literal bytes that follow. len is being set to the length of the string (more below).
db: compile time. the value stored in db is stored in the binary output by the assembler at a specific offset. equ allows you define constants that normally would need to be either hardcoded, or require a mov operation to get. db allows you to have data available in memory before the program even starts.
The pseudo instructions db
, dw
, dd
and friends can define multiple items
db 34h ;Define byte 34h
db 34h, 12h ;Define bytes 34h and 12h (i.e. word 1234h)
They accept character constants too
db 'H', 'e', 'l', 'l', 'o', 0
but this syntax is awkward for strings, so the next logical step was to give explicit support
db "Hello", 0 ;Equivalent of the above
P.S. In general prefer the user-level directives, though for [BITS]
and [ORG]
is irrelevant.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With