我目前正在使用x86汇编程序,因为我想刷新我的低级编程技能:-)。为了测试的目的,我试图编写一个函数,打印出给定的字符串。打印功能本身工作正常。在下一步中,我想从磁盘跳转到第二个汇编程序并打印出文本。在跳转到地址时从磁盘加载正常工作。使用x86汇编程序(nasm)进行打印功能的数据段问题
这里是给定的情景:
[... 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
所有这些程序工作正常。我面临的唯一问题是,没有文字印刷。在调试期间,我看到打印函数立即跳转到.PrintDone标签,因为SI中似乎没有数据,因此lodsb没有向al(除空字节外)加载任何数据。
我在考虑数据段可能有问题的事实。
因此,我添加了下面一行启动程序的开始:
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
解决了这个问题!
最佳 塞巴斯蒂安
它是否仍然会直接转到'.PrintDone',并且设置为'ds',还是只是不打印任何内容? (我想你想在中断之前使用'ah',而不是'ax'。) – ughoavgfhw 2012-01-29 04:32:53
嘿,斧头上的经典错字 - 再次固定到啊。现在该程序正在打印一些东西,但只是一个奇怪的字符。当检查寄存器当执行达到系统停止它们具有以下条目:ES = 07e0 00007e00 0000FFFF 00009300 CS = 07e0 00007e00 0000FFFF 00009b00 SS = 9000 00090000 0000FFFF 00009300 DS = 07e0 00007e00 0000FFFF 00009300 – 2012-01-29 04:48:51
我不认为中断会移动光标,这意味着如果打印多个字符,则只能看到最后一个。另外,请检查以确保'si'指向最后的正确位置。如果我计算正确,那么在“数据字段”评论中必须有24个字节的数据才是正确的。代码看起来很好。 – ughoavgfhw 2012-01-29 05:43:54