Loops 为什么此ASM功能不能正确打印?
我正在尝试编写一个小函数来打印特定内存位置中以null结尾或固定长度的字符串。这是我的密码:Loops 为什么此ASM功能不能正确打印?,loops,assembly,io,x86,mbr,Loops,Assembly,Io,X86,Mbr,我正在尝试编写一个小函数来打印特定内存位置中以null结尾或固定长度的字符串。这是我的密码: vbrstart: xor eax, eax mov sp, 0x7a00 mov bp, 0x6000 mov ss, ax mov ds, ax mov es, ax xor ebx, ebx xor ecx, ecx push strict dword initializing push strict word 0x0
vbrstart:
xor eax, eax
mov sp, 0x7a00
mov bp, 0x6000
mov ss, ax
mov ds, ax
mov es, ax
xor ebx, ebx
xor ecx, ecx
push strict dword initializing
push strict word 0x0000
call printmsg
jmp end
;push strict dword memloc
;push strict word length
;call printmsg
printmsg:
pop strict dword [store_ret]
mov [store_cx], cx
mov [store_esi], esi
pop cx
pop esi
push eax
push ebx
mov ah, 0x0E
mov bx, 0x0007
cmp cx, 0x0000
je printnullterm
printgivenlen:
lodsb
cmp cx, 0x0000
je printdone
int 10h
dec cx
jmp printgivenlen
printnullterm:
lodsb
cmp al, 0x00
je printdone
int 10h
jmp printnullterm
printdone:
pop ebx
pop eax
mov esi, [store_esi]
mov cx, [store_cx]
push strict dword [store_ret]
ret
printdata:
store_cx dw 0
store_esi dd 0
store_ret dd 0
end:
hlt
jmp end
initializing db 10,13,'Initializing...',0
测试时,它会不确定地打印,并且不会在空字节处停止。我在哪里出错了?您的堆栈没有与所有推送和弹出的对象正确对齐。检查传递的参数及其在例程中的使用情况。 首先,这里有一个提示:
vbrstart:
xor eax, eax
mov sp, 0x7a00
mov bp, 0x6000
mov ss, ax
mov ds, ax
mov es, ax
xor ebx, ebx
xor ecx, ecx
push strict dword initializing
push strict word 0x0000
call printmsg ; near call, only 16 bits ret addr stored
jmp end
;push strict dword memloc
;push strict word length
;call printmsg
printmsg:
pop strict dword [store_ret] ; pop dword (ret address + 16 bits- 1st argument)
mov [store_cx], cx ; store_cx = 0
mov [store_esi], esi ; store_esi = ??
pop cx ; cx = initializing
. . .
我发现您的代码有两个问题:
- 您已经编写了一个引导加载程序。这样的程序在16位实地址模式下运行。这意味着
的返回地址将是一个单词,而不是代码所期望的dword呼叫
printmsg: pop word [store_ret]
- 您以一种危险的方式设置堆栈。您需要首先更改SS寄存器,然后立即更改SP寄存器
xor ax, ax mov ss, ax <<< Keep these together mov sp, 0x7a00 <<< and in this order!
使用调试器看看哪里出了问题,怎么样?调试器没有详细说明哪个寄存器中有什么,以及调试的哪个部分被卡住。将其编译为调试器可以使用的ELF二进制文件,并将其编译为平面二进制文件,我使用它,添加到VBR,提供了不同的代码和结果,所以调试器并没有给我提供太多有用的信息。如果有人知道支持平面二进制文件的免费调试器,请告诉我。。。那会有很大帮助。。。我可以卸载或反汇编,但这是关于所有bochs内置调试器或将gdb附加到bochs或qemu的。PS:现在还不清楚你处于什么模式,小心混合16位和32位的东西,尤其是你的堆栈操作看起来很奇怪。所以我不需要存储ret地址?我首先想到的是我的论点?push word initializing ... pop si