标签: x86-16

为什么 16 位机器上的 20 个地址空间可以访问 1 兆字节而不是 2 兆字节?

好吧,这个问题听起来很简单,但我很惊讶。在 1 兆字节是大量内存的古代,英特尔试图弄清楚如何使用 16 位来访问 1 兆字节的内存。他们提出了使用段和偏移地址值来生成 20 位地址的想法。

现在,20 位给出了 2^20 = 1,048,576 个可以寻址的位置。现在假设我们访问每个地址位置 1 个字节,我们得到 1,048,576/(1024*1024) = 2^20/2^20 兆字节 = 1 兆字节。好的,明白了。

混乱来了,我们在古老的 8086 中有 16 位数据总线,一次可以访问 2 个字节而不是 1 个,这相当于 20 位地址可以访问总共 2 MB 的数据,对吗?当数据总线为 2 字节宽时,为什么我们假设每个地址只存储 1 个字节?我在这里很困惑。

memory processor cpu-architecture memory-address x86-16

5
推荐指数
2
解决办法
4054
查看次数

汇编程序如何计算符号地址的段和偏移量?

我已经学习了编译器和汇编语言,所以我想编写自己的汇编程序作为练习。但我有一些问题;

如何计算@DATA 或 OFFSET/ADDR VarA 等段的地址?

以一个简单的汇编程序为例:

    .model small
    .stack 1024
    .data
          msg db 128 dup('A')
    .code
    start:
        mov ax,@data
        mov ax,ds
        mov dx, offset msg
                           ; DS:DX points at msg
        mov ah,4ch
        int 21h            ; exit program without using msg
    end
Run Code Online (Sandbox Code Playgroud)

那么汇编器是如何计算段的段地址的@data呢?

它如何知道将什么放入立即数mov dx, offset msg

compiler-construction assembly masm memory-segmentation x86-16

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

8086 中的堆栈段和堆栈指针

我对 stack segment (ss) 和 stack pointer (sp) registers 有点困惑。当堆栈为空时,sp 值是否等于 ss 值?我读到当我们将一个字(2 字节)推入堆栈时,sp 减 2,如果第一条语句为真(sp=ss),那么我可以说如果堆栈不为空,堆栈指针的值总是较小或等于堆栈段的值是真的吗??。如果我们影响 sp 的值使其大于 ss 会发生什么?即:mov ss,200h mov sp,400h mov ax,1010h push ax

请纠正任何错误,提前thanx

assembly stack segment x86-16

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

TASM 1.4 - 显示特定颜色的字符串?

我正在使用 TASM 1.4,我正在尝试制作一个输出,该输出将在同一屏幕上显示不同颜色的句子。我可以制作一些显示彩色文本的东西,但所有单词都具有相同的颜色。如何制作显示不同颜色的字符串/句子的东西?例如,类似:

Hi, what group would you like to join?
The Founders
The Vox Populi
Run Code Online (Sandbox Code Playgroud)

“嗨,您想加入哪个小组?” 颜色为绿色。“创始人”的颜色是蓝色。“The Vox Populi”被涂成红色,也许我想要另一个闪烁的句子?我只能将它们全部显示为蓝色、红色或绿色。有什么帮助吗?谢谢。

assembly text colors tasm x86-16

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

汇编基础知识:输出寄存器值

我刚刚开始学习汇编语言,我已经陷入了“在屏幕上显示存储在寄存器中的十进制值”的部分。我使用 emu8086,任何帮助将不胜感激!:)

.model small  ;Specifies the memory model used for program to identify the size of code and data segments

org 100h      ;allocate 100H memory locations for stack

.data         ;the segment of the memory to declare/initialze the variables

var1 db 0006
var2 db 0002
var3 db 0001


.code           ;start of the code segment

main proc       ;start of the first procedure

mov bl, var1
add bl, var2
add bl, var3


mov ah, 00h   ; display  function here?
mov dl, bl    ; …
Run Code Online (Sandbox Code Playgroud)

assembly dos x86-16 emu8086

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

模拟器使用 int21h/ah=09h 显示“在 2000 个字节之后找不到错误字节 24h”

我必须使用EMU8086在汇编中做一个简单的计算器,但每次我尝试启动它时,EMU8086都会出现此错误:

INT 21h, AH=09h - 
address: 170B5
byte 24h not found after 2000 bytes.
; correct example of INT 21h/9h:
mov dx, offset msg
mov ah, 9
int 21h
ret
msg db "Hello$"
Run Code Online (Sandbox Code Playgroud)

我检查了其他东西,但没有错误:

data segment
    choice db ?
    snum1 db 4 dup(?)
    snum2 db 4 dup(?)
    sres db 4 dup(?)
    num1 db ?
    num2 db ?
    res db ?
    ;;menu1 db "Chose a function to procced", 10, 13, "Add [+]", 10, 13, "Sub [-]", 10, …
Run Code Online (Sandbox Code Playgroud)

x86 assembly dos x86-16 emu8086

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

缓冲输入的工作原理

下一个程序中的输入工作正常,但是当我要求显示输出时,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
查看次数

当它不是基址或索引寄存器时,为什么CX在16位汇编中使用'[]'?

每当我尝试这样做时,在DOSBox下使用MASM 6.15:

mov al, [cx]
Run Code Online (Sandbox Code Playgroud)

要么

mov al, [cx + bx]
Run Code Online (Sandbox Code Playgroud)

要么

mov al, [cx + 4]
Run Code Online (Sandbox Code Playgroud)

我收到错误:'只允许基本或索引注册'

但话说回来,让我说我有一个数组var1.如果我做:

.model small
.stack 4096

.data
 var1 BYTE 1, 2, 3, 4, 5, 6, 7, 8, 9

.code
main proc
mov ax, @data
mov ds, ax

mov cx, 5
mov al, [var1 + cx]

mov ah, 4Ch
int 21h
main endp
end main
Run Code Online (Sandbox Code Playgroud)

它工作得很好.为什么不给出与上面相同的错误?CX不是基址或索引寄存器.

[]运算符的整个工作本质是什么?

x86 assembly dos masm x86-16

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

如何在 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
查看次数