NASM с Bochs - Сборка - Печать строки

Я хочу напечатать строку и использую сборку NASM, Bochs для запуска программы и имею два простых файла. Я делаю очень простой загрузочный сектор, чтобы начать изучать сборку. Я пытаюсь учить себя и использую этот PDF: https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf Я пытаюсь создать свой собственный функция струнной печати.

Проблема:

; Question 4
; Put together all of the ideas in this section to make a self-contained function for printing
; null-terminated strings, that can be used as follows:
;
; A boot sector that prints a string using our function.
;
[org 0x7c00] ; Tell the assembler where this code will be loaded
mov bx, HELLO_MSG ; Use BX as a parameter to our function , so
call print_string ; we can specify the address of a string.
mov bx, GOODBYE_MSG
call print_string
jmp $ ; Hang
%include "print_string.asm"
; Data
HELLO_MSG:
db ’Hello , World!’, 0 ; <-- The zero on the end tells our routine
; when to stop printing characters.
GOODBYE_MSG:
db ’Goodbye!’, 0
; Padding and magic number.
times 510-($-$$) db 0
dw 0xaa55
; For good marks, make sure the function is careful when modifying registers and that
; you fully comment the code to demonstrate your understanding.

Мой код:

bootsect.asm

    org 0x7c00 ; Start at boot sector. Allows us to add offset for labels efficiently


    mov bx, loading_sys_msg
    calltest:
    call str_out
    ;jmp calltest

    jmp $ ; Jump forever. Because end of program lol

; Includes
    %include "str_out.asm"

; Database Resources

    loading_sys_msg:
    db 'Loading OIK v0.0.1', 0

; Padding and magic BIOS number.

times 510-($-$$) db 0
dw 0xaa55
`

str_out.asm

;
; String-printing function
;
str_out:
pusha
pop bx
;add bx, 0x7c00 ; Adds current address if boot sect and no org called (not used)
mov ah, 0x0e    ; BIOS teletyping for 0x10 interrupt
mov ax, 0x00    ;prep counter
mov al, [bx]    ; character to print placed in al (bx address contents)
prnt:                   ; printing loop
int 0x10            ; interrupt print
add ax, 0x01    ; add to counter for removal afterwards
add bx, 0x01    ; move bx address forward by 1
mov al, [bx]    ; character to print placed in al (bx address contents)
cmp al, 0           ; Compare [al -?- 0]
jg prnt             ; If greater, jump to print
sub bx, ax      ;remove the counter amount
;sub bx, 0x7c00 ;remove address addition if used earlier (not used)
push bx
popa

Конфигурация Bochs:

# Tell bochs to use our boot sector code as though it were
# a floppy disk inserted into a computer at boot time.
floppya: 1_44=boot_sect.bin, status=inserted
boot: a

Когда Bochs загружается, экран очищается и ничего не происходит. Что я делаю неправильно?

(Спасибо Джестеру за сообщение, что я не указал проблему. Я все еще новичок в переполнении стека.)

1 ответ

str_out отсутствует инструкция RET, но не отображается из-за того, что вы хлам AH

mov ah, 0x0e    ; BIOS teletyping for 0x10 interrupt
mov ax, 0x00    ;prep counter

Обычно я не даю пример для упражнений, но в этом случае вы приложили разумные усилия, и можно получить определенную логику.

            org     0x7c00

            mov     bx, Msg
            call    str_out
            hlt
            jmp     $ - 1

str_out:    mov     ah, 0x0e
prnt:       mov     al, [bx]
            int     0x10
            add     bx, 0x01
            cmp     al, 0
            jg      prnt
            ret

  Msg:      db      'Loading OIK v0.0.1', 0

    times 510-($-$$) db 0
        dw  0xaa55

Не совсем уверен, что подразумевается под тем, чтобы убедиться, что функция осторожна при изменении регистров, но этот пример работает. Поскольку это, по сути, точная копия вашего кода, все, что вам нужно сделать, это документировать его, но есть две особенности, о которых вас могут спросить. Почему вы использовали инструкции и почему они в таком порядке?

Другие вопросы по тегам