【发布时间】:2012-01-29 04:07:34
【问题描述】:
我目前正在使用 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
所有这个程序都运行良好。我面临的唯一问题是,没有打印文本。在调试过程中,我看到打印函数立即跳转到 .PrintDone 标签,因为 SI 中似乎没有数据,因此 lodsb 不向 al 加载任何内容(除了空字节)。
我在想一个事实,数据段可能有问题。
因此,我在 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
解决问题!
最好的 塞巴斯蒂安
【问题讨论】:
-
它仍然直接进入
.PrintDone并添加到设置ds,还是它只是不打印任何东西? (我想你想要在中断之前ah,而不是ax。) -
嘿,斧头上的经典错字 - 再次固定为 ah。现在程序正在打印一些东西,但只有一个奇怪的字符。当执行到达系统停止时检查寄存器时,它们具有以下条目: ES =07e0 00007e00 0000ffff 00009300 CS =07e0 00007e00 0000ffff 00009b00 SS =9000 00090000 0000ffff 00009300 DS =07e0 000070
-
我认为中断不会移动光标,这意味着如果打印多个字符,您只会看到最后一个。另外,检查以确保
si指向最后的正确位置。如果我数对了,“数据字段”注释中必须有 24 个字节的数据才能正确。代码看起来不错。 -
您好,问题已通过将中断向量函数从 0Ah 替换为 0xE 得到解决……现在一切正常!感谢您的帮助!