Question

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??

Était-ce utile?

La solution

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.

Autres conseils

Let's step by step:

    jmp 0x7c0:start    ;jump to start

start:

     mov ax, cs        ; set up segments             
     mov ds, ax
     mov es, ax


     mov al,03h        ; Set up screen to 80 by 25
     mov ah,0
     int 10h

String is not executable code so put it before start label and after jmp. String must finish with zero character!

 welcome db "This is insane now"#0

 mov si, welcome     ;Print string
 call print_string

Missing finalize code to exit program properly so print_string will perform again

print_string:
     cld          ;Clear direction flag instruction is missing
     lodsb        

     or al, al    ; test if zero char
     jz .done     ; exit if zero char
     mov ah, 0x0E ; Write Char in Teletype Mode 
     mov bh, 0    ; Define 0 page if we have multiple pages
     int 0x10     ; print character!
     jmp print_string
    .done:
     ret
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top