[英]Data segment issue with x86 Assembler (nasm) for print function
我正在玩x86汇编程序,因为我想刷新我的低级编程技巧:-)。 出于测试目的,我尝试编写一个只打印出给定字符串的函数。 打印功能本身工作正常。 在另一个步骤中,我想从磁盘跳转到它加载第二个汇编程序,然后打印出一个文本。 在跳转到地址时从磁盘加载工作正常。
这是给定的场景:
[... 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
所有这个程序都运行正常。 我面临的唯一问题是,没有打印文字。 在调试过程中,我看到print函数立即跳转到.PrintDone标签,因为SI中似乎没有数据,因此lodsb不会加载任何数据(除了null字节)。
我在想这个事实,数据段可能有问题。
因此,我在Start-Routine的开头添加了以下行:
xor ax, ax ; clear ax register
mov ax, cs
mov ds, ax ; set data segment pointer
但这对程序行为没有任何改变。 什么都没打印。
执行到达暂停指令时检查CPU寄存器,给出以下结果:
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
你有什么线索在这里发生了什么吗?
[编辑 - 问题已解决]
更换:
mov ah, 0Ah -> mov ah, 0xE
解决了这个问题!
最好的塞巴斯蒂安
有一些问题。
首先,您没有正确设置功能0Ah的寄存器。 您必须将bh
设置为页码(0),将cx
设置为重复计数(1)。
其次,这个BIOS功能不会使光标位置前进,所有字符都会被打印到屏幕上的相同位置,相互覆盖,这应该只会导致'!' 可见,因为它是最后一个角色。
我建议改用函数0Eh。
第三,你没有初始化lodsb
依赖的方向标志( flags.df
)。 您应该使用cld
重置df
。
第四,我没有看到所有代码,但是你应该使用正确的org
指令为指令和数据生成正确的偏移量。
此外, NMIs
和SMIs
将导致hlt
完成, hlt
的代码将执行(以下是您的Print
)。 你想在循环中执行hlt
。
通过这些修复,我们得出:
bits 16
org 1
jmp Start
;data fields
msg db "Hello World!",0
Start:
mov ax, cs
mov ds, ax ; set data segment pointer
cld
mov si, msg ; load message to SI register
call Print
cli
.halt:
hlt ; halt the system
jmp .halt
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
; xor bh, bh
; mov cx, 1
mov ah, 0Eh ; function - print text tty
int 0x10 ; BIOS interrupt
jmp .PrintLoop ; continue with next char
.PrintDone:
ret
通过编译上面的nasm blah.asm -f bin -o blah.bin
得到的二进制文件应该加载到0x7e0:0001
并跳转到jmp 0x7e0:0001
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.