I am currently playing around with x86 assembler since I wanted to refresh my skills for low level programming :-). For testing purposes I tried to write a function that just prints out a given string. The printing function itself works fine. In a further step I wanted to load a second assembler program from disk jump to it and just print out a text. Loading from disk at jump to the address works fine.
Here is the given scenario:
[... loading from disk etc ... program is loaded to 0x7e0:0001]
jmp 0x7e0:0001
[... context of other asm ...]
jmp Start
;data fields
msg db "Hello World!",0
Start:
xor si, si ; clear SI register
mov si, msg ; load message to SI register
call Print
cli
hlt ; halt the system
Print:
.PrintLoop:
lodsb ; load byte from SI register
or al, al ; check if 0 byte
jz short .PrintDone ; if so - stop
mov ah, 0Ah ; function - print text to cursor
int 0x10 ; BIOS interrupt
jmp .PrintLoop ; continue with next char
.PrintDone:
ret
All of this program is working fine. The only problem that I face is, that no text is printed. During debugging I saw that the print function immediately jumps to the .PrintDone label since there seems to be no data in SI and therefore lodsb loads nothing to al (besides null byte).
I was thinking about the fact, that there might be something wrong with the data segment.
Thus, I added the following line at the beginning of the Start-Routine:
xor ax, ax ; clear ax register
mov ax, cs
mov ds, ax ; set data segment pointer
But this changed nothing regarding the programs behaviour. Nothing is printed.
Inspecting the CPU registers when execution reaches halt instruction, gives the following:
EAX=00000a00 EBX=00000000 ECX=00000002 EDX=00000000
ESI=00000026 EDI=00000000 EBP=00000000 ESP=0000ffff
EIP=00000036 EFL=00000046 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=1
ES =07e0 00007e00 0000ffff 00009300
CS =07e0 00007e00 0000ffff 00009b00
SS =9000 00090000 0000ffff 00009300
DS =07e0 00007e00 0000ffff 00009300
Do you have any clue what's going on here?
[EDIT - PROBLEM RESOLVED]
Replacing:
mov ah, 0Ah -> mov ah, 0xE
fixes the problem!
Best Sebastian
.PrintDonewith your addition to setds, or does it just not print anything? (I think you wantahjust before the interrupt, notax.)siis pointing to the right spot at the end. If I counted right, there must be 24 bytes of data at the "data fields" comment for it to be right. The code looks fine.