I have got a piece of code which runs in realmode and printf a message on screen,I am using Dosbox 0.7 as my execution environment .Below is the code
jmp 0x7c0:start
start:
mov ax, cs ; set up segments
mov ds, ax
mov es, ax
mov al,03h
mov ah,0
int 10h
welcome db "This is insane now"
mov si, welcome
call print_string
print_string:
lodsb ; grab a byte from SI
or al, al ; logical or AL by itself
jz .done ; if the result is zero, get out
mov ah, 0x0E
int 0x10 ; otherwise, print out the character!
jmp print_string
.done:
ret
I am able assemble this code fine but when I run this ,It just hangs there and a message I can see in linux terminal
Illegal read from b0671921, CS:IP 7c0: 4468
This is how I am assembling it
nasm PRINT.ASM -o out.com
I have tried searching this message in google and found it could be a problem with DOSBox version.
Can anybody let me know what could be the problem here??
The problem with the code is the place of the string constant. It must be placed where it will never be "executed" because it is not a code.
Another issue is how the code ends. The boot record should load some other code (OS kernel, or bigger boot program) and jump to it. Or at least (if you only want to test something) simply make infinite loop. In your case, the program falls to the print_string subroutine and then tries to "return" to nowhere.
Here is the fixed version:
org 7c00h
start:
mov ax, cs ; set up segments
mov ds, ax
mov es, ax
mov al, 03h
mov ah, 0
int 10h
mov si, welcome
call print_string
.sleep:
jmp .sleep
print_string:
lodsb ; grab a byte from SI
test al, al ; logical or AL by itself
jz .done ; if the result is zero, get out
mov ah, 0x0E
int 0x10 ; otherwise, print out the character!
jmp print_string
.done:
ret
welcome db "This is insane now", 0
Why the jump is removed? The BIOS, after loading the boot sector from the disk, places it on address 0000h:7c00h. Respectively, it jumps to $0000:$7c00 in order to start the execution of the code.
As long as (probably) the inial code was compiled at offset $0000, the first jump simply changes the segment to 7c0h and offset to 0000h in order to provide proper execution of the program.
But we can set the origin of our program to 7c00h (org 7c00h) and this way simply avoid using one more instruction.