Assembly 8086不打印第一个字符,而是打印空字符
此代码中有一个错误。print_字符串在指向字符串后不会打印到屏幕上,它只在代码Assembly 8086不打印第一个字符,而是打印空字符,assembly,nasm,x86-16,bootloader,bios,Assembly,Nasm,X86 16,Bootloader,Bios,此代码中有一个错误。print_字符串在指向字符串后不会打印到屏幕上,它只在代码mov bx,8000h中的行被删除并且它后面的两行被删除时才会打印,但是我无法写入大量字节来ram调用alloc并将basepointer增加20倍后整个过程崩溃。我该怎么做,我该如何写字符串,使它在写了20个字节后不会崩溃 [bits 16] [org 0x7c00] SEAM_STD_BUFFER equ 0 SEAM_STD_LIMIT equ 255 xor ax,ax mov bx,ax mov bx
mov bx,8000h
中的行被删除并且它后面的两行被删除时才会打印,但是我无法写入大量字节来ram调用alloc并将basepointer增加20倍后整个过程崩溃。我该怎么做,我该如何写字符串,使它在写了20个字节后不会崩溃
[bits 16]
[org 0x7c00]
SEAM_STD_BUFFER equ 0
SEAM_STD_LIMIT equ 255
xor ax,ax
mov bx,ax
mov bx,cx
mov dx,0
mov ds,bx
mov es,bx
mov bp,0
mov sp,bp
mov ss,bp
mov bx,8000h
mov sp,bx
mov ss,bx
mov bp,0
jmp _start
_start:
call clear
.repeat:
mov bp, OS_USERNAME_DESCRIPT
call print_string
call Set_BasePointer_std
call read_string_show
jmp .repeat
Set_BasePointer_std:
mov bp,SEAM_STD_BUFFER
ret
read_char_show:;() returns al
call read_char
cmp al,8
je .back
call print
ret
.back:
cmp bp,SEAM_STD_BUFFER
je .done
call print
.done:
mov al,0
ret
read_string: ; (ptr bp place to allocate string)
call read_char
cmp al,13
je .done
call alloc
inc bp
cmp bp,SEAM_STD_LIMIT
jge .resetbp
jmp read_string
.done:
mov al,0
call alloc
ret
.resetbp:
call Set_BasePointer_std
jmp read_string
read_string_show: ; (ptr bp place to allocate string)
call read_char_show
cmp al,0
je read_string_show
cmp al,13
je .done
cmp al,8;;NOT GOOD ENOUGH
je .skip;;NOT GOOD ENOUGH
call alloc
inc bp
.skip:;;NOT GOOD ENOUGH
cmp bp,SEAM_STD_LIMIT
jge .resetbp
jmp read_string_show
.resetbp:
call Set_BasePointer_std
jmp read_string
.done:
mov al,0
call alloc
call next_line
ret
read_char: ;() returns al
mov ax,0x00
int 0x16
ret
clear:; ()
mov ah,0
mov al,3
int 0x10
ret
free:;(bp ptr at place start to free, ax at end )
mov [bp],byte 0
cmp bp,ax
je .done
inc bp
jmp free
.done:
ret
dalloc:; (ptr bp)
mov al,[bp]
ret
alloc: ;(bp place to allocate,al byte value)
mov [bp], al
ret
clear_line:
mov dh,0
call clear
ret
next_line:
mov ah,2
mov dl,0
inc dh
cmp dh ,25
jge clear_line
int 10h
ret
previous_line:
dec dh
mov ah,2
mov dl,0
int 10h
ret
next_char:; finish
string_compare:;finish
print: ; (al Character to print, bl color)
mov ah,0x0E
int 10h
ret
print_string: ;(ptr bp Place of string start)
call dalloc
cmp al,0
je .done
call print
inc bp
jmp print_string
.done:
ret
OS_WELCOME db 'What is giong on',0
OS_USERNAME_DESCRIPT db 'Username:'
times (510 - ($-$$)) db 0x00
dw 0xAA55
让你的印刷步入正轨
设置堆栈的方式有很多错误。做两次也帮不了什么忙!此外,在设置堆栈指针时,始终首先分配SS
,然后立即分配SP
。订单很重要
对于放入SS
的实际值,坦率地说,您别无选择。(从技术上讲,您有,但我们不要让事情复杂化…)考虑到您希望使用BP
指向字符串,并且整个程序都使用ORG 0x7C00
进行编码,SS
中唯一正确的值是零。我建议你写:
xor ax, ax
mov ss, ax
mov sp, 0x7C00
这将把堆栈放在引导加载程序的正下方,一个安全的地方。因为
DS
和ES
也需要良好的初始化,所以要使整个过程:
xor ax, ax
mov ss, ax
mov sp, 0x7C00
mov ds, ax
mov es, ax
这个打印例程仍然需要您说出BIOS电传打字功能应该写入哪个显示页面。通过
BH
寄存器进行选择
print:
mov bh, 0
mov ah, 0x0E
int 10h
ret
为了验证打印是否有效,您可以让程序等待一个键:
_start:
call clear
.repeat:
mov bp, OS_USERNAME_DESCRIPT
call print_string
mov ah, 00h ;Wait for a key
int 16h ;Wait for a key
一旦您确信这部分代码工作正常,您只需删除这两行代码
最终会适得其反的事情 请使用显式零结束字符串。不要依赖以下恰好使用零的填充 今后:
- 您可以使用非零的其他值填充
- 引导加载程序可能很拥挤,因此根本没有填充
它处理的是在输入了大量字符后程序不断崩溃的事实 问题在于这一行: 和它的同伴: 由于堆栈段现在正确定位为0,因此不应再存储从
bp=0开始的字符。您可以在alloc codemov[bp],al
中执行此操作
您可以将它存储在许多其他地方,但一个好的位置将直接位于引导加载程序后面
SEAM_STD_BUFFER equ 0x7E00
你是16位汇编代码开发新手吗?我问你,因为你的函数操作方式、不寻常的dalloc例程以及你在代码顶部错误地设置了段寄存器。是的,我是新手,请告诉我如何设置段寄存器。我将从一开始就非常简单。暂时忘记输入。你有没有尝试过创建只在屏幕上显示字符串的工作代码?是的,它可以很好地打印所有内容,除了我添加mov bp,8000h mov ss,bp它会出错。你已经标记了这个emu8086。它看起来像nasm。您使用的是emu8086吗?谢谢您的回答:),输入这么多字符后代码仍然会冻结,我确实更改了初始化,在字符串中添加了终止符,并在打印标签中指定了页码。谢谢,但是为什么不在[0:0]中移动内容呢x86上的work?@Dodo中断向量表占用内存中从0000h:0000h->0000h:0400h的1024个最低地址。如果你在这个区域写随机的东西,那么中断向量就会被破坏,很快计算机就会挂起!
print:
mov bh, 0
mov ah, 0x0E
int 10h
ret
_start:
call clear
.repeat:
mov bp, OS_USERNAME_DESCRIPT
call print_string
mov ah, 00h ;Wait for a key
int 16h ;Wait for a key
OS_USERNAME_DESCRIPT db 'Username:'
times (510 - ($-$$)) db 0x00
SEAM_STD_BUFFER equ 0
mov bp,SEAM_STD_BUFFER
SEAM_STD_BUFFER equ 0x7E00