编写在QEMU中作为引导加载程序运行的x86实模式汇编程序时遇到问题.我正在尝试通过BIOS中断0x10打印文本.我的代码是:
print:
pusha
.loop:
mov AL, [SI]
cmp AL, 0
je .end
call printChar
inc SI
jmp .loop
.end:
popa
ret
printChar:
pusha
mov AH, 0x0E
mov BH, 0
mov BL, 0x0F
int 0x10
popa
ret
Run Code Online (Sandbox Code Playgroud)
我[ORG 0x7c00]用作原点.我测试了printChar标签,并在AL中用一些字母调用它,它工作正常.当我尝试将内存地址加载到这样的消息时:
loadMsg db "Loading",0
mov SI, loadMessage
call print
Run Code Online (Sandbox Code Playgroud)
我在QEMU仿真器上输出像'U'这样的垃圾作为输出.昨天,我编写了一个与此类似的代码,完全没有问题.是什么导致了我的问题以及如何解决?
我正在尝试学习汇编并编写引导程序.以下代码将软盘驱动器的内容加载到内存并跳转到它(开始在地址0x1000加载).此代码应该在屏幕上打印"X",但由于某种原因,它会打印一个空格.有人可以告诉我有什么问题吗?
[bits 16]
jmp reset
reset: ;Resets floppy drive
xor ax,ax ;0 = Reset floppy disk
mov dl,0 ;Drive 0 is floppy
int 0x13
jc reset ;If carry flag was set, try again
mov ax,0x1000 ;When we read the sector, we are going to read address 0x1000
mov es,ax ;Set ES with 0x1000
floppy:
mov ah,0x2 ;2 = Read floppy
mov al,0x11 ;Reading one sector
mov ch,0x0 ;Track 1
mov cl,0x2 ;Sector 2, track 1
mov dh,0x0 ;Head 1
mov …Run Code Online (Sandbox Code Playgroud) 我目前正在尝试编写16位实模式启动代码,该代码打印一个字母,然后从软盘加载第二个段并跳转到该段,然后再打印一个字母。
但是,我对“从云端硬盘读取扇区”呼叫的工作方式有些困惑。到目前为止,这是我的代码:
[BITS 16]
org 0x7B00
start:
mov ax, 0xB800 ; Video buffer
mov es, ax ; Copy address of video buffer to extra segment
mov byte [es:0], 'A' ; Move character A to first address
mov byte [es:1], 0x17 ; Format for blue background, white foreground
mov ah, 0x02 ; Read sectors from drive
mov al, 1 ; Read 1 sector
mov ch, 0 ; Cylinder 0
mov cl, 0 ; Sector 0
mov dh, 0 ; Head 0 …Run Code Online (Sandbox Code Playgroud) 我正在尝试学习操作系统的工作方式。这是我要解决的一个容易的任务:编写一个简单的引导程序,提示用户输入他的名字并打印欢迎消息,例如“ hello,>> name <<”-之后,它什么也不做。
如果minix 3与qemu此相关,我正在与一起运行。我只是将asm文件dd及其前512个字节编译为/dev/c0d0(的虚拟硬盘minix)。
我可以打印消息并打印用户输入的内容。但是,此后我没有设法打印用户名。
这是我的汇编代码:
[bits 16]
[org 0x7c00]
mov si, HelloString
call print_string
mov di, name
call read_name
mov si, name
call print_string
read_name:
read_char:
mov ah, 0h ; read character from keyboard
mov [di], ah ; save it in the buffer
inc di ; next char
int 0x16 ; store it in AL
cmp ah, 0x0d ; check for enter
je stop_reading
mov …Run Code Online (Sandbox Code Playgroud) 有人知道下面的代码有什么问题吗?
我无法让它按照我想要的方式工作。我只想打印变量的单个字符(字母“h”)。
为此,我只需通过方括号使用间接寻址来复制内容
[]
; Set BIOS print screen settings
mov ah, 0x0e ; Teletype
mov bh, 0 ; Page number
mov bl, 4 ; Red on black (00000100 - High 0000 is black, low 0100 is red)
mov cx, 1 ; Writes one character
; Printing to screen
mov al, [msg] ; Copy the contents of 'H' into 'al'; IT SEEMS THIS IS NOT WORKING!!!
jmp print_char ; Jump to executable code and do not let CPU step on …Run Code Online (Sandbox Code Playgroud) 我一直在搞乱x86-16程序集并使用VirtualBox运行它.出于某种原因,当我从内存中读取并尝试将其作为角色打印时,我得到的结果与我期望的完全不同.但是,当我将字符硬编码为指令的一部分时,它工作正常.这是代码:
ORG 0
BITS 16
push word 0xB800 ; Address of text screen video memory in real mode for colored monitors
push cs
pop ds ; ds = cs
pop es ; es = 0xB800
jmp start
; input = di (position*2), ax (character and attributes)
putchar:
stosw
ret
; input = si (NUL-terminated string)
print:
cli
cld
.nextChar:
lodsb ; mov al, [ds:si] ; si += 1
test al, al
jz .finish
call putchar
jmp .nextChar
.finish:
sti
ret …Run Code Online (Sandbox Code Playgroud) 我正在学习x86实模式编程,并使用QEMU编写了一个小型引导加载程序来测试它.我选择了GNU汇编程序来学习.
这是汇编代码:
#
# boot.s
#
.section .text
.globl start
start:
//setup stack
mov $0x7c0, %ax
mov %ax, %ss
mov $512, %sp
//setup video
mov $0x0, %eax
mov $0x0, %al
int $0x10
//print a character say 'm'
mov $'m', %al
mov $0x0E, %ah
int $0x10
1:
jmp 1b
Run Code Online (Sandbox Code Playgroud)
QEMU显示屏上显示以下文本:
从硬盘启动...
问题:打印上面的消息,它似乎仍然没有做任何事情.
我用来组装的脚本链接是:
> to assemble : gcc -c boot.s
> to link : ld -T link.ld boot.o -o b.bin
> to put on bootsector of Hard-disk …Run Code Online (Sandbox Code Playgroud) 我正在制作一个运行 Snake 的操作系统,并且我处于 32 位保护模式,但我无法在屏幕上绘制像素。我在实模式下切换到模式 0x13 (320x200x256),屏幕一片空白。进入保护模式后,内核运行并且我正在绘制的像素不会出现。
我从这篇OSDev 文章中汲取灵感,该文章切换到保护模式并将像素绘制到视频显示上。
这是kernel.c
#include "display.h" // Include Display Drivers
#include "constants.h" // Include constants that C doesn't have included
#include "keyboard.h" // Include the custom keyboard driver
void _start(){} // Remove LD Warning
DisplayDetails globalDisplayDetails; // The display details.
int main(){
// Init the display details
DisplayDetails details = display_init();
globalDisplayDetails = details;
bool running = true;
while(running){
// This is the OS loop
putpixel(100, 100, 0x00FFFFFF);
} …Run Code Online (Sandbox Code Playgroud)