我想做一个16位汇编的小操作系统。在这段代码中,我创建了一种“终端”,在这里我接受用户输入,如果输入是shutdown,则启动函数关闭所有内容,否则什么都不会发生,循环继续(现在,稍后我将创建其他函数,因此如果命令不是“shutdown”,则其他检查将开始查看它是否是另一个命令)
代码:
bits 16
section .kernel
global _start_kernel
_start_kernel:
mov ax, 0x3
int 10h
commandLoop:
mov si, user
call print
mov di, input_string
call input
mov si, input_string
call print
ifCommandShutdown:
cld
mov si, C_shutdown
mov di, input_string
mov cx, CL_shutdown
cmpsb
jz thenCommandShutdown
elseCommandShutdown:
call newLine
jmp commandLoop
thenCommandShutdown:
call shutdown
exit:
cli
hlt
%include "lib/console.asm"
%include "lib/system.asm"
user: db "user >> ", 0
input_string:
;- Commands Variables ------------------------------+
; |
C_shutdown: db "shutdown", 0 ; |
C_reboot: db "reboot" , 0 ; |
; |
CL_shutdown: db $ - C_shutdown ; |
CL_reboot: db $ - C_reboot ; |
; |
;---------------------------------------------------+
times 512-($-$$) db 0
字符串
console.asm:
print:
mov ah, 0x0e
characterLoop:
lodsb
or al, al
jz break
int 10h
jmp characterLoop
break:
ret
input:
mov ah, 0x0
int 16h
ifKeyIsEnter:
cmp al, 0x0D
jz enterIsPressed
elseEnterKey:
stosb
mov ah, 0x0e
int 10h
jmp input
enterIsPressed:
mov al, 0x0
stosb
call newLine
ret
newLine:
mov ah, 0x0e
mov al, 13
int 10h
mov al, 10
int 10h
ret
型
system.asm:
shutdown:
mov ax, 0x1000
mov ax, ss
mov sp, 0xf000
mov ax, 0x5307
mov bx, 0x0001
mov cx, 0x0003
int 0x15
型
编译时没有错误,但在qemu中它总是关闭
1条答案
按热度按时间myss37ts1#
cmps
始终返回0看看你是如何布局内存的(忘记为输入分配空间):
字符串
输入只是覆盖了你将要比较的文本。显然,一个字符比较
cmpsb
总是会找到匹配。因为你要验证和查看的是完整的单词'shutdown':
型
如果您 * 尝试在CX* 中设置计数,则应在
cmpsb
指令前添加repe
(RepeatWhileEqual)前缀。当前加载计数是错误的,因为您使用字节大小的变量 CL_shutdown 的地址加载它,而您需要该变量的实际内容。但最好将这些长度定义为相等:
型
然后,要比较的代码变为(假设DS和ES已正确设置并且彼此相等):
的字符串
另一个错误是 shutdown。
mov ax, 0x1000
mov ax, ss
指令没有意义(加载AX两次)。应改为:型