我的目标是使用 Int 16 指令能够使用箭头键在程序中上下移动,直到我的用户决定按退出键。我是否在循环中使用以下代码读取多个按键并在末尾添加终止条件,或者是否缺少某些内容?
Mov ah,00
int 16
Run Code Online (Sandbox Code Playgroud) 我希望能够使用正常的 ASM 功能将一些值推送到堆栈。
例如
push ax
push bx
push cx
push dx
Run Code Online (Sandbox Code Playgroud)
我想使用堆栈框架以任何顺序访问这些。
假设我想按照 C、B、A、D 的顺序弹出这些,而不仅仅是必须这样做......
pop dx
pop cx
pop bx
pop ax
Run Code Online (Sandbox Code Playgroud)
使用 SP/BP 执行此操作的最佳/最有效方法是什么,以便我可以在需要时抓取东西,而不必在每次使用初始 4 AX 到 DX 值时不断推送和弹出?
我正在用汇编语言开发一个操作系统。\n在某个时间我从 NASM 收到此错误:
\n\n\n\n\nos.asm:113: 错误: TIMES 值 -138 为负数
\n
我想把这个项目进行到底。只有这样的错误才让我绝望!
\n\n这是代码:
\n\nBITS 16\n\nstart:\n mov ax, 07C0h ; Set up 4K stack space after this bootloader\n add ax, 288 ; (4096 + 512) / 16 bytes per paragraph\n mov ss, ax\n mov sp, 4096\n mov ax, 07C0h ; Set data segment to where we're loaded\n mov ds, ax\n call cls\n MOV AH, 06h ; Scroll up function\n XOR AL, AL ; Clear entire screen\n XOR …Run Code Online (Sandbox Code Playgroud) 我知道 8086 有一个 BIU 和一个 EU,这有助于处理器的流水线化。BIU 有一个 6 字节预取队列,用于提取指令指针指向的地址后面的字节。现在,当要执行的指令是跳转到另一个位置的指令时,预取的所有 6 个字节会发生什么情况?它们会被冲掉然后重新加载吗?(这会破坏处理器的流水线效率,不是吗?)
我有一个简单的程序,它将一些以空结尾的字符串移动到寄存器bx:
[org 0x7c00] ; Tells the assembler where the code will be loaded
mov ah, 0x0e
mov bx, HELLO_MSG ; Moves string inside of HELLO_MSG to bx
call print_string ; Calls the print_string function inside of ./print_string.asm
mov bx, GOODBYE_MSG ; Moves string inside of GOODBYE_MSG to bx
call print_string
jmp $ ; Hangs
%include "print_string.asm"
HELLO_MSG:
db 'Hello, World!', 0
GOODBYE_MSG:
db 'Goodbye!', 0
times 510-($-$$) db 0
dw 0xaa55
Run Code Online (Sandbox Code Playgroud)
和一个print_string内部函数./print_string.asm:
print_string:
mov …Run Code Online (Sandbox Code Playgroud) 在开发 86-DOS 应用程序lDebug的分支期间,我遇到了称为“Intel 组”的指令类别。具体来说,组是指与使用相同 1 或 2 个操作码字节的一组指令相关的东西,通过/rModR/M 字节的字段来区分。
“Intel 组”类别可以一直追溯到 1997 年发布的 FreeDOS Debug 0.95,并且可以在我的 fddebug 存储库的修订版中看到:
/*
* Here are the tables for the main processor groups.
*/
struct {
int seq; /* sequence number of the group */
int info; /* which group number it is */
}
grouptab[] = {
{0x80, GROUP(1)}, /* Intel group 1 */
{0x81, GROUP(1)},
{0x83, GROUP(2)},
{0xd0, GROUP(3)}, /* Intel group 2 */
{0xd1, GROUP(3)},
{0xd2, …Run Code Online (Sandbox Code Playgroud) SS、SP、BP的初始值是多少?它们是否为空 (0x0) 或者例如 SP 是否立即设置为 0xFFFE?
当我们编写汇编代码而不使用 pop 和 push 语句时,堆栈指针是否设置为一个值?
我一直在模拟 IBM 5150、PC-DOS 1.0、IBM Macro Assembler 1.0 上进行汇编。(86框3.7.1)
我从一个简单的“Hello World”开始:
stack segment stack
db 80h dup(?)
stack ends
data segment
msg db 'Hello World!',13,10,'$'
data ends
code segment
assume cs:code,ds:data
mov dx, seg msg
mov ds, dx
mov dx, offset msg
mov ah, 09h
int 21h
int 20h
code ends
end
Run Code Online (Sandbox Code Playgroud)
遗憾的是,程序在输出后崩溃了。通过调试我发现,在 21h 中断之后,DS、CS 和 IP 寄存器被损坏。
a:debug hello.exe
-r
AX=0000 BX=0000 CX=0000 DX=0000 SP=0080 BP=0000 SI=0000 DI=0000
DS=049F ES=049F SS=04B1 CS=04AF IP=0000 NV UP DI PL NZ …Run Code Online (Sandbox Code Playgroud) 在实模式和 32 位保护模式下,16 位寻址用于通过 ModR/M 字节来引用存储器。此寻址仅在使用旧前缀的 i386 指令中受支持,在 x86-64 指令中完全不受支持。
然而,ModR/M 字节也被 8 位特定操作码使用,这让我怀疑原始16 位 x86 指令集中是否存在 8 位寻址。尽管 8 位地址非常有限,但完全可以使用不同的操作码以与 16 位指令相同的方式对此类指令进行编码。
例如,代替
add (bx, si), ax
Run Code Online (Sandbox Code Playgroud)
你会有
add (bl, dh), al
Run Code Online (Sandbox Code Playgroud)
很难找到任何 i386 之前的文档,所以我一无所知。这曾经被支持过吗?
中断ah=0Eh int 10h在屏幕上显示一个字符,它有几个参数,其中包括BH,本来应该表示页码,但是经过几次测试我发现BH完全没有用。即使我更改页码,无论如何,字符仍将显示在活动页面上。
“日期为 1981/4/24 和 1981/10/19 的 IBM PC ROM 要求 BH 与当前活动页面相同”
互联网上的一个页面这样写道: https: //www.ic.unicamp.br/~celio/mc404-2004/service_interrupts#int10h_0Eh
此功能在屏幕上显示一个字符,根据需要推进光标并滚动屏幕。打印始终在当前活动页面上进行。
我必须信任哪个来源,我使用没有操作系统的虚拟盒子,并且我使用引导加载程序。
我明确表示我不理解此信息
1981/4/24 和 1981/10/19 的 IBM PC ROM 要求 BH 与当前活动页面相同
知道我使用 Virtual Box,我不认为 Virtual Box 使用 1981 年 IMG PC 上的 ROM?
x86-16 ×10
assembly ×9
x86 ×5
bios ×3
machine-code ×2
nasm ×2
boot ×1
bootloader ×1
dos ×1
intel ×1
interrupt ×1
masm ×1
osdev ×1
real-mode ×1
virtualbox ×1