In the previous chapter we learnt on how to print character in the console. Now, we will learn how to print a complete string in the console.
Theory
org
directive:
In assembly language, ORG (origin) is a directive that tells the assembler where to place the code or data in memory. It sets the starting address for the code or data that follows it.
Here's the syntax for ORG
directive:
ORG address
address
: is the memory address where the code or data should be located.
For example, in the case of a bootloader written for a PC that loads at memory address 0x7C00, you would use ORG 0x7C00 to specify that the code should be loaded at that memory address.
[ORG 0x7C00] ; Set origin to 0x7C00, where BIOS loads the bootloader
or
; Set origin to 0x7C00, where BIOS loads the bootloader
ORG 0x7C00
lodsb
:
It is an x86 assembly language instruction that loads the byte at the address stored in the DS:SI
register pair into the AL
register, and then increments or decrements the SI
register, depending on the direction flag (DF
).
Here's a breakdown of how lodsb
works:
- lodsb loads the byte at the memory location addressed by DS:SI into the AL register.
- If the direction flag (DF) is clear (0), SI is incremented by 1 after the operation.
- If the direction flag (DF) is set (1), SI is decremented by 1 after the operation.
For Example:
mov si, msg ; Set SI to point to the start of the message
print_string:
lodsb ; Load the byte from [DS:SI] into AL and increment SI
; AL now contains the byte that was loaded from memory
Understanding the lodsb
Instruction:
The lodsb
instruction is used to load a byte from memory into the AL
register. Here' how it works:
print_string:
lodsb ; Load the byte from [DS:SI] into AL and increment SI
lodsb
loads the byte at the memory location addressed byDS:SI
into the AL register.- After the operation, the
SI
register is automatically incremented to point to the next byte in memory.
Defining Strings
In assembly language, strings are defined using the DB
(Define Byte) directive. Here's how you can define strings:
msg DB 'Hello, World!', 0 ; Our null-terminated string
DB
is used to define bytes.'Hello, World!'
is the string you want to define.0
is the null terminator, which marks the end of the string.
Printing String to the Console
Though it sounds difficult, but its very easy. We just have to do the same thing we did during previous chapter for printing character in the console. This time we have to do it for every character in the string. So, we can use some kind of loop to call the same interrupt routine with different character of string. We would need lodsb
instruction for this operation.
[ORG 0x7C00]
mov si, msg ; Set SI to point to the start of the message
print_string:
lodsb ; Load the byte from [SI] into AL and increment SI
cmp al, 0 ; Check if AL is the null terminator
je done ; If AL is 0, we're done
mov ah, 0x0E ; BIOS teletype function
mov bh, 0x00 ; Page number
mov bl, 0x07 ; Text attribute (white on black)
int 0x10 ; BIOS video interrupt
jmp print_string ; Repeat for the next character
done:
cli ; Disable interrupts
hlt ; Halt the CPU
msg db 'TheJat!', 0 ; Our null-terminated string
times 510 - ($ - $$) db 0 ; Fill the rest of the sector with zeros
dw 0xAA55 ; Boot signature

Using Loop Statement
The loop instruction is a useful construct in x86 assembly language for creating loops. It decrements the CX register and jumps to a specified label if the CX register is not zero. It's commonly used in combination with other instructions to repeat a block of code a specific number of times.
Here's how it works:
loop label
- The
loop
instruction decrements theCX
register by1
. - If the
CX
register is not zero after decrementing, the loop instruction jumps to the specified label.
Here's the modified string printing bootloader code using loop statement:
[ORG 0x7C00] ; Set origin to 0x7C00, where BIOS loads the bootloader
mov si, msg ; Set SI to point to the start of the message
mov cx, 13 ; Length of the string
print_string:
mov al, [si] ; Load the byte from [DS:SI] into AL
cmp al, 0 ; Check if AL is the null terminator
je done ; If AL is 0, we're done
mov ah, 0x0E ; BIOS teletype function
mov bh, 0x00 ; Page number
mov bl, 0x07 ; Text attribute (white on black)
int 0x10 ; BIOS video interrupt
inc si ; Increment SI to point to the next character
loop print_string ; Repeat for the next character
done:
cli ; Disable interrupts
hlt ; Halt the CPU
msg db 'Hello, World!', 0 ; Our null-terminated string
times 510 - ($ - $$) db 0 ; Fill the rest of the sector with zeros
dw 0xAA55 ; Boot signature
Explanation:
- We initialize SI to point to the start of the string.
- We use CX register to keep track of the number of characters to print.
- Inside the loop, we load the byte from the memory location addressed by SI into the AL register.
- We compare AL with the null terminator to check if we have reached the end of the string.
- If not, we print the character to the screen using BIOS interrupt 0x10.
- Finally, we increment SI to point to the next character in the string and repeat the process until CX becomes zero.