标签: x86-16

INT 16h/AH=0h 不等待引导加载程序中的按键

我使用 GNU 汇编器和 AT&T 语法编写了我的第一个引导加载程序。它应该打印hello world到屏幕上,然后通知用户按任意键将导致重新启动。只有按下某个键后才会启动重新启动。我的引导加载程序代码不等待按键,并在打印信息后自动重新启动。为什么此代码不等待击键,我该如何修复它?

我的引导扇区代码:

#generate 16-bit code
.code16

#hint the assembler that here is the executable code located
.text
.globl _start;
#boot code entry
_start:
  jmp _boot                           #jump to boot code
  welcome: .asciz "Hello, World\n\r"  #here we define the string
  AnyKey: .asciz "Press any key to reboot...\n\r"
 .macro mWriteString str              #macro which calls a function to print a string
      leaw  \str, %si
      call .writeStringIn
 .endm

 #function to print the string
 .writeStringIn:
      lodsb
      orb  %al, %al …
Run Code Online (Sandbox Code Playgroud)

assembly gnu-assembler bootloader att x86-16

5
推荐指数
1
解决办法
1354
查看次数

关于 8086 程序集的 DB 和 DUP 指令

所以我遇到了一个问题,让我质疑我对DB(define byte) 和DUP(duplicate) 指令的基本理解。我对它们的理解方式是:

  • NUM DB 34将创建一个名为NUM的变量,并为其分配值 34。类似于 C char NUM = 34;1
  • NUM DB 34 DUP(?)会给我一个包含 34 个项目的数组,每个项目都未分配。
  • NUM DB 3 DUP(4)会给我一个名为NUM的数组,其中包含 3 个项目:4、4、4。

它是否正确?

在我的教科书中我遇到过:

PRINT_SELECT DB 133 (?)
             DB 123 (?)
Run Code Online (Sandbox Code Playgroud)

这只是教科书上的一个错误,还是这两行代码完全有其他含义?


脚注 1:(编者注):NUM = 34在 asm 中定义了一个不存储在数据存储器中的汇编时常量。在 MASM 语法汇编器中,它的工作方式与某些上下文中的变量类似。但例如mul NUM仅适用于内存源,不适用于立即数, whileimul eax, ecx, NUM或 ,shl ax, NUMmov ax, NUM / 2仅适用于立即数,不适用于内存源。

assembly directive x86-16

5
推荐指数
1
解决办法
1万
查看次数

如何在汇编中播种随机数生成器?

我试图在汇编中创建一个完整的随机数,但每次启动程序时,它都会以相同的顺序给出相同的数字。如果数字是 12、132、4113 等,每次我启动代码时它都会重复它们。

我试图制作的程序有点像猜谜游戏。

    IDEAL
MODEL small
STACK 100h
DATASEG
;vars here
RNG_Seed dw ? 

CODESEG
; Generates a pseudo-random 15-bit number.
; Parameters: <none>
; Clobbers:   AX, DX
; Returns:    AX contains the random number
proc GenerateRandNum
   push bx
   push cx
   push si
   push di


   ; 32-bit multiplication in 16-bit mode (DX:AX * CX:BX == SI:DI)
   mov  ax, [RNG_Seed]
   xor  dx, dx
   mov  cx, 041C6h
   mov  bx, 04E6Dh
   xor  di, di
   push ax
   mul  bx
   mov  si, dx
   xchg …
Run Code Online (Sandbox Code Playgroud)

random x86 assembly x86-16

5
推荐指数
1
解决办法
2284
查看次数

缓冲输入的工作原理

下一个程序中的输入工作正常,但是当我要求显示输出时,DOS 根本不显示任何内容!这怎么可能?

        ORG     256
        mov     dx, msg1
        mov     ah, 09h                 ;DOS.WriteString
        int     21h
        mov     dx, buf
        mov     ah, 0Ah                 ;DOS.BufferedInput
        int     21h
        mov     dx, msg2
        mov     ah, 09h                 ;DOS.WriteString
        int     21h
        mov     dx, buf
        mov     ah, 09h                 ;DOS.WriteString
        int     21h
        mov     ax, 4C00h               ;DOS.TerminateWithExitcode
        int     21h
; --------------------------------------
msg1:   db      'Input : ', '$'
buf:    db      20 dup ('$')
msg2:   db      13, 10, 'Output : ', '$'
; --------------------------------------
Run Code Online (Sandbox Code Playgroud)

assembly dos input x86-16

5
推荐指数
1
解决办法
5928
查看次数

X86 IDIV 余数符号取决于 8/-3 和 -8/3 的被除数符号?

谁能帮我解释一下为什么在这些情况下余数的符号不同?这是模拟器错误还是真实的 CPU 也会这样做?

在此输入图像描述

8 / -3 : quotient(AL) = -2 remainder(AH) =  2
-8 / 3 : quotient(AL) = -2 remainder(AH) = -2
Run Code Online (Sandbox Code Playgroud)

assembly integer-division x86-16 emu8086

5
推荐指数
1
解决办法
979
查看次数

ORG指令后设置段寄存器

我目前正在关注操作系统开发教程,其中包括有关引导加载程序的讨论。

我的引导加载程序当前处于 16 位实模式,因此,我能够使用提供的 BIOS 中断(例如 VGA 视频中断等)。

BIOS 提供视频中断0x10(即视频电传输出)。视频中断具有功能0x0E,它允许我将字符打印到屏幕上。

这是这个基本的引导加载程序:

org     0x7c00              ; Set program start (origin) address location at 0x7c00.
                            ; This program is loaded by the BIOS at 0x7c00.
bits    16                  ; We live in 16-bit Real Mode.

start:  
        jmp loader

bootmsg     db      "Welcome to my Operating System!", 0        ; My data string.

;-------------------------------------------------------
;   Description:    Print a null terminating string
;-------------------------------------------------------
print:
    lodsb                   ; Load string byte at address DS:SI …
Run Code Online (Sandbox Code Playgroud)

nasm cpu-registers segment memory-segmentation x86-16

5
推荐指数
1
解决办法
1747
查看次数

从另一个文件调用过程

我有一个 .ASM 文件,我想在其中调用另一个 .ASM 或 .INC 文件中的过程。
我尝试将以下内容写入我的main.asm文件中:

INCLUDE file_op.inc
Run Code Online (Sandbox Code Playgroud)

然而,当我尝试运行它时,它只是说:

“模拟器已停止。”

当它第一次遇到另一个文件中指定的过程时,它会执行此操作。

另一个 .INC 文件中的过程是:

; A function to open a file using its name and remember its file_handle 
open_file       proc
                mov ax, 3d00h           ; System call to open a file
                lea dx, file_name       ; name of the file we are opening
                int 21h                 ; system interrupt
                mov file_handle, ax     ; remember file_handle!!
                ret
                endp

; A function to read from a file byte by byte using …
Run Code Online (Sandbox Code Playgroud)

assembly dos tasm x86-16 emu8086

5
推荐指数
1
解决办法
1842
查看次数

如何在 x86 实模式引导加载程序中初始化堆栈以防止与 BIOS 冲突?

假设我想将堆栈初始化为S字节大小。

我想选择堆栈的基本位置,B以便随着堆栈从 向下增长B,我最终不会覆盖引导加载程序或 BIOS 使用的任何代码或其他内存。

由于我自己编写引导加载程序(并且初始 MBR 扇区被加载到线性地址0x7c00),防止与引导加载程序发生冲突似乎是一个仔细规划的问题。

我如何知道 BIOS 代码所在的位置,以及我的堆栈是否可能覆盖 BIOS 正在使用的任何内存?

另外,是否可以保证初始ss:sp值指向哪里,以及在不设置新值的情况下可以安全使用多少堆栈空间?

assembly callstack bios bootloader x86-16

5
推荐指数
1
解决办法
133
查看次数

扩展内联汇编中的约束“Rah”和“Ral”是什么意思?

这个问题的灵感来自另一个论坛上某人提出的问题。在以下代码中,扩展内联程序集约束RahRal含义是什么。我以前没见过这些:

#include<stdint.h>

void tty_write_char(uint8_t inchar, uint8_t page_num, uint8_t fg_color)
{
    asm (
        "int $0x10"
        :
        : "b" ((uint16_t)page_num<<8 | fg_color),
          "Rah"((uint8_t)0x0e), "Ral"(inchar));
}

void tty_write_string(const char *string, uint8_t page_num, uint8_t fg_color)
{
    while (*string)
        tty_write_char(*string++, page_num, fg_color);
}

/* Use the BIOS to print the first command line argument to the console */
int main(int argc, char *argv[])
{
    if (argc > 1)
        tty_write_string(argv[1], 0, 0);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

特别是在这段代码中使用RahRal作为约束:

asm ( …
Run Code Online (Sandbox Code Playgroud)

x86 gcc inline-assembly x86-16 ia16-gcc

5
推荐指数
1
解决办法
148
查看次数

在引导加载程序中使用的正确调用约定是什么?

我正在尝试编写一个引导加载程序和一个非常原始和基本的内核,以了解裸机编码实践和技术。无论如何,我正在使用 NASM 编写我的引导程序。我的代码正在运行,但我对要使用的调用约定有疑问。

我只是通过运行 NASM 来编译我的引导加载程序: nasm bootloader.asm -o bootloader

在我的汇编代码,我写的功能,如BlDisplayString通过BIOS中断显示字符串int 0x10AH = 0x13。我试图__fastcall通过在CX, DX, STACK. 这是在 16 位代码中使用的正确调用约定标准吗?当我调用这些函数时,CPU 未处于保护模式并且仍处于实模式。

assembly operating-system calling-convention bootloader x86-16

5
推荐指数
1
解决办法
109
查看次数