我的内核函数“EXEC”有问题[已解决]

问题描述 投票:0回答:1

我正在编写一个 16 位 x86 汇编操作系统,并且正在开发程序执行。我设计的执行是不同的,因为我希望内核执行代码(这样它可以对程序想要做什么有更多的控制,所以如果它想覆盖驱动器A:用户会被通知),不是CPU。所以我正在编写

exec.asm
文件,其中的函数将读取程序并执行相应的指令。在解释我的问题之前,我会将源代码留给您。

dload.asm
DLOAD:
    PUSHA
    MOV AH, 0X02
    
    MOV AL, 0X04
    MOV CH, 0X00
    MOV CL, 0X02
    MOV DH, 0X00
    MOV DL, BL
    MOV BX, 0X0000
    MOV ES, BX
    MOV BX, 0X7E00
    
    INT 0X13
    JC DERRR

DSUCC:
    POPA
    MOV AL, 0X00
    RET

DERRR:
    POPA
    MOV AL, 0X01
    RET
print.asm
PRINT_CHR:
    PUSHA
    MOV AH, 0X0E
    
    MOV AL, [BX]
    INT 0X10
    
    POPA
    RET

PRINT_STR:
    PUSHA
    
    MOV AH, 0X0E

PRINT_STR_LOOP:
    MOV AL, [BX]
    
    CMP AL, 0X00
    JE END_PRINT_STR
    
    INT 0X10
    
    INC BX
    JMP PRINT_STR_LOOP

END_PRINT_STR:
    POPA
    RET
screen.asm
SHOW_BASIC_SCREEN:
    PUSHA
    
    MOV AH, 0X0E
    MOV BX, PNAME_OFFSET
    MOV CX, 0X14
    
SHOW_PNAME:
    MOV AL, [BX]
    
    CMP CX, 0X00
    JE SHOW_PNAME_END
    
    INT 0X10
    
    INC BX
    DEC CX
    
    JMP SHOW_PNAME
    
SHOW_PNAME_END:
    MOV AL, '='
    
    INT 0X10
    INT 0X10
    
    MOV CX, 0X12

AFTER_PNAME_SPACES:
    MOV AL, ' '
    
    CMP CX, 0X00
    JE END_SPACING
    
    INT 0X10
    
    DEC CX
    
    JMP AFTER_PNAME_SPACES

END_SPACING:
    MOV AL, '='
    
    INT 0X10
    INT 0X10
    
    MOV AL, ' '
    INT 0X10

    MOV AL, '}'
    INT 0X10
    
    MOV CX, 0X24
    
SHOW_INPUT_SPACE:
    MOV AL, ' '
    
    CMP CX, 0X00
    JE END_INPUT_SPACE
    
    INT 0X10
    
    DEC CX
    JMP SHOW_INPUT_SPACE

END_INPUT_SPACE:
    MOV CX, 0X16

CLOSE_PNAME:
    MOV AL, '='
    
    CMP CX, 0X00
    JE CLOSE_PNAME_END
    
    INT 0X10
    
    INC BX
    DEC CX
    
    JMP CLOSE_PNAME

CLOSE_PNAME_END:
    MOV CX, 0X12

CLOSE_SPACES:
    MOV AL, ' '
    
    CMP CX, 0X00
    JE CLOSE_SPACES_END
    
    INT 0X10
    
    DEC CX
    
    JMP CLOSE_SPACES

CLOSE_SPACES_END:
    MOV CX, 0X28

CLOSE_INPUT:
    MOV AL, '='
    
    CMP CX, 0X00
    JE CLOSE_INPUT_END
    
    INT 0X10
    
    DEC CX
    
    JMP CLOSE_INPUT

CLOSE_INPUT_END:
    POPA
    RET

PNAME_OFFSET EQU 0X9000
setc.asm
_SETC:
    MOV AH, 0X02
    MOV AL, 0X00
    MOV BH, 0X00
    
    INT 0X10
    
    RET
cscr.asm
CSCR:
    PUSHA
    
    MOV CX, BX
    MOV AH, 0X0E
    
CSCR_LOOP:
    MOV AL, 0X0A
    
    CMP CX, 0X00
    JE CSCR_END
    
    INT 0X10
    
    DEC CX
    JMP CSCR_LOOP

CSCR_END:
    MOV AH, 0X02
    MOV BH, 0X00
    MOV DH, 0X00
    MOV DL, 0X00
    
    INT 0X10
    
    POPA
    RET
exec.asm
EXEC_INC:
    INC BX

EXEC:
    PUSHA
    
    MOV BX, 0X02
    CALL CSCR
    
    CALL SHOW_BASIC_SCREEN
    
    POPA
    
    MOV AL, [BX]
    
    CMP AL, 0X00
    JE _0X00
    
    CMP AL, 0X50
    JE _0X50
    
    CMP AL, 0X51
    JE _0X51
    
    CMP AL, 0X49
    JE _0X49
    
    CMP AL, 0X4A
    JE _0X4A
    
    CMP AL, 0X3C
    JE _0X3C
    
    CMP AL, 0X52
    JE _0X52
    
    CMP AL, 0X53
    JE _0X53
    
    CMP AL, 0X3E
    JE _0X3E
    
    CMP AL, 0X7F
    JE _0X7F
    
    JMP EXEC_ERR

_0X50:
    PUSHA
    
    MOV DH, 0X03
    MOV DL, 0X00
    CALL _SETC
    
    POPA
    
    INC BX
    
    MOV AH, 0X0E
    MOV AL, [BX]
    
    INT 0X10
    
    JMP EXEC_INC

_0X51:
    PUSHA
    
    MOV DH, 0X03
    MOV DL, 0X00
    CALL _SETC
    
    POPA
    
    INC BX
    MOV AH, 0X0E
    
_0X51_LOOP:
    MOV AL, [BX]
    
    CMP AL, 0X00
    JE EXEC_INC
    
    INT 0X10
    
    INC BX
    JMP _0X51_LOOP

_0X49:
    PUSHA
    
    MOV DH, 0X00
    MOV DL, 0X2D
    CALL _SETC
    
    MOV AH, 0X00
    MOV BX, INPUT_ADDR
    
    INT 0X16
    
    MOV [BX], BYTE AL
    
    POPA
    
    JMP EXEC_INC

_0X4A:
    PUSHA
    
    MOV DH, 0X00
    MOV DL, 0X2D
    CALL _SETC
    
    MOV BX, INPUT_ADDR

_0X4A_LOOP:
    MOV AH, 0X00
    INT 0X16
    
    CMP AL, 0XD
    JE _0X4A_END
    
    CMP AL, 0X7F
    JE _0X4A_DEL
    
    MOV [BX], BYTE AL
    
    MOV AH, 0X0E
    INT 0X10
    
    INC BX
    JMP _0X4A_LOOP

_0X4A_DEL:
    DEC BX
    MOV [BX], BYTE 0X00
    
    JMP _0X4A_LOOP
    
_0X4A_END:
    MOV [BX], BYTE 0X00
    POPA
    
    JMP EXEC_INC

_0X3C:
    INC BX
    MOV AH, [BX]
    
    INC BX
    MOV AL, [BX]
    
    PUSHA
    
    MOV BX, PADDR
    MOV [BX], BYTE AH
    
    INC BX
    MOV [BX], BYTE AL
    
    POPA
    
    JMP EXEC_INC

_0X52:
    PUSHA
    
    MOV DH, 0X03
    MOV DL, 0X00
    CALL _SETC
    
    MOV BX, PADDR
    MOV AH, [BX]
    
    INC BX
    MOV AL, [BX]
    
    MOV BX, AX
    
    MOV AH, 0X0E
    MOV AL, [BX]
    
    INT 0X10
    
    POPA
    
    JMP EXEC_INC

_0X53:
    PUSHA
    
    MOV DH, 0X03
    MOV DL, 0X00
    CALL _SETC
    
    MOV BX, PADDR
    MOV AH, [BX]
    
    INC BX
    MOV AL, [BX]
    
    MOV BX, AX
    MOV AH, 0X0E
    
_0X53_LOOP:
    MOV AL, [BX]
    
    CMP AL, 0X00
    JE _0X53_END
    
    INT 0X10
    
    INC BX
    JMP _0X53_LOOP

_0X53_END:
    POPA
    
    JMP EXEC_INC

_0X3E:
    MOV BX, PADDR
    MOV AH, [BX]
    
    INC BX
    MOV AL, [BX]
    
    MOV BX, AX
    ADD BX, 0X9000
    
    JMP EXEC

_0X7F:
    PUSHA
    
    MOV DH, 0X00
    MOV DL, 0X00
    
    CALL _SETC
    
    MOV BX, 0X19
    CALL CSCR
    
    POPA
    
    JMP EXEC_INC
    
_0X00:
    RET

EXEC_ERR:
    MOV DH, 0X03
    MOV DL, 0X00
    CALL _SETC
    
    MOV BX, EXEC_ERR_MSG
    CALL PRINT_STR
    
EXEC_ERR_MSG:
    DB "Error executing program.", 0X0A, 0X0D, "Unrecognized instruction code.", 0X0A, 0X0D, 0X00

PADDR EQU 0X8C00
boot.asm
[ORG 0X7C00]

MOV BP, 0XF000
MOV SP, BP

__MAIN:
    MOV BX, DSKL_MSG
    CALL PRINT_STR
    
    MOV BL, DL
    CALL DLOAD
    
    CMP AL, 0X01
    JE __ERR
    
    MOV BX, DONE_DSKL_MSG
    CALL PRINT_STR
    
    MOV BX, KSTART_MSG
    CALL PRINT_STR
    
    JMP KOFFSET
    
__ERR:
    MOV BX, ERRR_DSKL_MSG
    CALL PRINT_STR

    JMP __END

DSKL_MSG:
    DB "Loading disk at 0x0000:0x7e00...", 0X0A, 0X0D, 0X00

DONE_DSKL_MSG:
    DB "Disk loaded successfully at 0x0000:0x7e00.", 0X0A, 0X0D, 0X00

ERRR_DSKL_MSG:
    DB "Fatal: unable to read disk. Cannot load kernel and boot the system.", 10, 13, 0

KSTART_MSG:
    DB "Starting kernel... ", 0X0A, 0X0D, 0X00

KOFFSET EQU 0X7E00

%INCLUDE "print.asm"
%INCLUDE "dload.asm"

__END:
    JMP $
    
    TIMES 510 - ( $ - $$ ) DB 0X0
    DW 0XAA55
kernel.asm
[ORG 0X7E00]

__KSTART:

    MOV BX, KSTARTED_MSG
    CALL PRINT_STR
    
    MOV BX, 25
    CALL CSCR
    
__MAIN:
    MOV BX, 0X02
    CALL CSCR
    
    MOV [0X9000], BYTE 'P'
    MOV [0X9001], BYTE 'A'
    MOV [0X9002], BYTE 'R'
    MOV [0X9003], BYTE 'R'
    MOV [0X9004], BYTE 'O'
    MOV [0X9005], BYTE 'T'
    MOV [0X9006], BYTE ' '
    MOV [0X9007], BYTE ' '
    MOV [0X9008], BYTE ' '
    MOV [0X9009], BYTE ' '
    MOV [0X900A], BYTE ' '
    MOV [0X900B], BYTE ' '
    MOV [0X900C], BYTE ' '
    MOV [0X900D], BYTE ' '
    MOV [0X900E], BYTE ' '
    MOV [0X901F], BYTE ' '
    MOV [0X9010], BYTE ' '
    MOV [0X9011], BYTE ' '
    MOV [0X9012], BYTE ' '
    MOV [0X9013], BYTE ' '
    MOV [0X9014], BYTE 0X4A
    MOV [0X9015], BYTE 0X3C
    MOV [0X9016], BYTE 0X8A
    MOV [0X9017], BYTE 0X00
    MOV [0X9018], BYTE 0X53
    MOV [0X9019], BYTE 0X7F
    MOV [0X901A], BYTE 0X3C
    MOV [0X901B], BYTE 0X00
    MOV [0X901C], BYTE 0X14
    MOV [0X901D], BYTE 0X3E
    MOV [0X901E], BYTE 0X00
    
    CALL SHOW_BASIC_SCREEN
    
    MOV BX, 0X9014
    CALL EXEC
    
KSTARTED_MSG:
    DB "Kernel started successfully.", 0X0A, 0X0D, 0X00

INPUT_ADDR EQU 0X8A00

%INCLUDE "print.asm"
%INCLUDE "cscr.asm"
%INCLUDE "screen.asm"
%INCLUDE "setc.asm"
%INCLUDE "exec.asm"
    
    JMP $

EXEC 正在 0x9014 处运行程序。

今天我在

exec.asm
文件中写入了0X7F指令(用于清除屏幕)。现在它可以工作了,但是 0X50、0X51、0X52 和 0X53 指令发生了一些变化(分别打印字符、打印字符串、BX 指向的字符和 BX 指向的空终止字符串)。在这些说明的开头,您可以看到以下代码片段:

    PUSHA
    
    MOV DH, 0X03
    MOV DL, 0X00
    CALL _SETC
    
    POPA

用于将光标设置在屏幕的第4行,但由于某种原因,自从我添加了0X7F指令后,它就被绕过了。即使我在 DH 中存储一个大数字(用于存储光标必须在其中移动的行的寄存器),如果调用打印函数,也会在第三行打印我的字符或字符串。

我使用 NASM 将

boot.asm
kernel.asm
编译为两个单独的文件,
boot.bin
kernel.bin
,因此我将这两个文件复制到另一个文件
main.bin
(使用 Windows CMD 命令
copy boot.bin/b+kernel.bin/b main.bin
) )这是我使用 Bochs Emulator 2.8 启动的可启动启动项。

我希望您能理解我的问题(如果您需要更多信息,请告诉我,我将使用必要的信息编辑帖子)! 非常感谢。

assembly kernel nasm intel x86-16
1个回答
1
投票

您正在执行命令 0x53,就在命令 0x7F 之前

_0X7F: PUSHA MOV DH, 0X00 MOV DL, 0X00 CALL _SETC MOV BX, 0X19 CALL CSCR

由于数字 0X19(十进制 25),屏幕将在顶部滚动

1 行。打印在第 4 行 (3) 的文本现在位于第 3 行 (2)。

© www.soinside.com 2019 - 2024. All rights reserved.