标签: x86-16

如何在8086中生成物理地址?

8086体系结构中,内存空间__CODE__大小分为多个逻辑段__CODE__.

即它有20个地址线,因此使用以下方法:

数据段寄存器向左移位4位然后加到偏移寄存器

我的问题是:虽然所有寄存器只有16位,但我们如何进行移位操作

microprocessors memory-address x86-16

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

MOV AX,CS和MOV DS,AX的概念

有人可以解释三个指令的功能.....

>      ORG 1000H 
>      MOV AX,CS
>      MOV DS,AX
Run Code Online (Sandbox Code Playgroud)

我知道什么是代码,数据,理论上的额外段.

但,

1.他们如何在这些计划中实施?

2.为什么他们将整个部分移动到另一部分?(MOV AX,CS; MOV DS,AX;)

(对不起,如果问题是荒谬的)这两条指令真正概念是什么......

/*以下给出的8086组装程序运行良好.

我可以理解这段代码中每条指令的含义,

除了突出显示的3条指令.*/

代码接受输入,直到0被击中!

Code:
    ASSUME CS:CODE        
    CODE SEGMENT 
    ORG 1000H
    MOV AX,CS
    MOV DS,AX
BACK:
   MOV AH,01H
   INT 21H
   CMP AL,'0'
   JZ LAST
   JMP BACK
LAST:
   MOV AX,4C00H
   INT 21H
   CODE ENDS

   END
Run Code Online (Sandbox Code Playgroud)

assembly x86-16

4
推荐指数
2
解决办法
3万
查看次数

无法将8位地址移动到16位寄存器

我试图分配变量来注册这里是代码:

       ORG 100h

        var1 DB 10  ;
        var2 DB 20  ;

        MOV BX,var1 ; error : operands do not match: 16 bit register and 8 bit address
RET
END
Run Code Online (Sandbox Code Playgroud)

但如果换掉第4行:

MOV BL, var1;
Run Code Online (Sandbox Code Playgroud)

有用.所以我的问题是为什么不能8位变量移动到更大的16位寄存器中

我已经提到了这个,这个这个 OP,但它没有回答我的问题.

注意:

  1. 我正在使用emu8086汇编程序
  2. 我是汇编语言的新手,所以如果这是一个愚蠢的问题,我道歉.

x86 assembly x86-16 emu8086

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

在不使用C库的情况下在0xb8000处显示文本视频内存

我一直在用C编写内核.我一直在使用GCC交叉编译器,在Windows系统上编写并以16位实模式为目标.我没有可用于编写内核的C库.我已经开始使用一些代码来假设将字符直接打印到屏幕上.这是一个函数来自kernel.c:

int main()
{
  char *src = (char *)0xB8000000L;
  *src = 'M';
  src += 2;
  *src = 'D';
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用GCC编译了我的代码,并使用参数-m16生成将在实模式下运行的代码.我使用这些命令来生成我的kernel.bin:

gcc -ffreestanding -c -m16 kernel.c -o kernel.o
ld -Ttext 0x10000 -o kernel.pe kernel.o
objcopy -O binary kernel.pe kernel.bin
Run Code Online (Sandbox Code Playgroud)

Stack Overflow用户Michael Petch解决了我的链接器问题,但评论代码本身是不正确的.他发表了这样的评论:

除链接器问题外,您是否尝试将旧的TurboC/MSVC 16位代码转换为GCC?我发现(char*)0xB8000000L可疑.如果它是一个真正的16位C编译器,它可能是好的,如果它是(char far*)0xB8000000L.GCC不是一个真正的16位C编译器,并没有旧式远指针的概念.所以,即使你得到这个代码进行编译,这可能不会做你认为它做的,我假设从-m16选项与GCC你正在尝试创建一个实模式16位内核(而不是保护模式一个) )?

我一直在尝试printf在C中为我自己的操作系统实现自己的类似功能.我上面提供的代码只是我理解的一小部分.我在程序集中创建了一个bootloader(8086).

迈克尔是对的吗?如果是这样,我该如何解决这个问题并直接写入视频内存0xb8000

assembly kernel real-mode osdev x86-16

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

如何在DOS中获得额外的段?

我想编写一个DOS程序(我的第一个程序),我有点没有经验。

对于该程序,我需要超过64 KB的(传统)内存。如何获得额外的内存?理想情况下,我想为程序增加两个64k的内存块。我可以开始将数据写入地址空间中的某个地方还是需要请求额外的内存吗?

assembly memory-management dos gnu-assembler x86-16

4
推荐指数
3
解决办法
1035
查看次数

使用自己的键盘中断`int 09h`处理程序时代码的奇怪行为(损坏的绘制)

我正在为univesity工作,我们需要创建一个简单的breakout/arkanoid克隆,它很顺利但是我发现了一个会删除屏幕上所有内容的bug,这个bug是随机的,但我怀疑它与我的DrawPaddle功能.也许你可以发现错误或了解为什么视频内存会这样做.

游戏必须使用16位ms-dos程序集完成,我使用NASM + VAL + Dosbox创建它,我用以下代码编译它:

nasm -f obj test.asm
val test.obj
Run Code Online (Sandbox Code Playgroud)

游戏只是使用键盘箭头在固定屏幕上移动球拍,您也可以通过按下退出退出游戏.

这是一切都还好:https://puu.sh/yeKtG/affc912d4b.png,当程序溢出时它看起来像这样:http://puu.sh/yeKEy/caeef089d1.pnghttp:// puu.sh/yeKJH/1106e1e823.png

我注意到奇怪的行为只发生在我移动桨时它会随机发生,例如现在我从程序中删除了几乎所有其他东西,它可能需要几次尝试来获取bug.

这是DrawPaddle代码:

DrawPaddle:
    push di
    mov di, [paddleposition]
    mov cx, 5 ;the paddle will be 5 pixels tall
.p0:
    push cx
    mov cx, paddlesize
.p1:
    mov byte [es:di], bl
    inc di
    loop .p1
    add di, screenweight - paddlesize
    pop cx
    loop .p0
    pop di
    ret
Run Code Online (Sandbox Code Playgroud)

这是完整的代码,它使用键盘处理程序读取输入,并使用320x200x256直接写入视频内存.

BITS 16

stacksize       EQU 0200h

;Constantes
;Direccion de inicio de la …
Run Code Online (Sandbox Code Playgroud)

assembly dos nasm x86-16

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

使用GAS AT&T指令计算引导扇区的填充长度?

所以我想在bootsector中添加填充.比方说,目前只有一个无限循环:jmp ..扇区需要512字节长.此外,0xaa55需要在最后添加的幻数.

jmp .
.skip 508, 0
.word 0xaa55
Run Code Online (Sandbox Code Playgroud)

但是,如果我想打印一些但不想将所有字节计算到适当大小的内容,该怎么办?
在Intel/NASM中,语法是:

; print something
times 510-($-$$) db 0
dw 0xaa55
Run Code Online (Sandbox Code Playgroud)

但在AT&T语法中呢?好了,循环(.rept)在这里不起作用,因为这里.不需要给出绝对值.我们和.skip/ 有同样的问题.space,他们也需要一个绝对值.

是否有使用某种循环/ .align/ .skip/ etc 添加填充的方法?

编辑:我as用来构建和链接,ld -Ttext 0x7c00 --oformat binary直到yasmAT&T语法足够稳定.

assembly gnu-assembler bootloader att x86-16

4
推荐指数
2
解决办法
810
查看次数

可以修改C中的字符串文字吗?

最近我有一个问题,我知道一个指向常量数组的指针(在下面的代码中初始化)位于该.rodata区域中,并且该区域仅可读。但是,我在模式C11中看到,此内存地址行为的写入将是不确定的。我知道Borland的Turbo-C编译器可以在指针指向的地方写,这是因为处理器在当时的某些系统上以实模式运行,例如MS-DOS?还是与处理器的操作模式无关?使用保护模式下的处理器,是否还有其他编译器可以写入指针并且不会导致任何内存破坏失败?

#include <stdio.h>

int main(void) {
    char *st = "aaa";
    *st = 'b'; 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在此代码与MS-DOS中的Turbo-C一起编译时,您将能够写入内存

c gcc x86-16

4
推荐指数
2
解决办法
208
查看次数

汇编:没有malloc和syscall的动态内存分配?[FreeDOS应用程序]

我的问题是关于程序集(尤其是MASM)中动态内存分配的逻辑。关于此主题的文章很多,所有文章都依赖于malloc或brk的使用。但是,根据我的理解,必须(或可以)将malloc作为C语言的一部分,用汇编语言编写。等同于brk,因为它是操作系统的一部分,因此也写在C上,可以用汇编1对1替换。很久以前,我在PCMag中看到了一篇有关使用纯asm在MS-DOS中进行动态内存分配的文章。不幸的是,我已经失去了这段精彩作品的所有痕迹。现在我' m与FreeDOS(可精确引导的FreeDOS闪存卡)一起工作,并且想知道如果有人决定编写自己的内存分配器该如何进行?不依赖操作系统机制的内存分配的起点和逻辑是什么?

assembly dos heap-memory dynamic-memory-allocation x86-16

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

如何实现 Int 16h 以使用键盘浏览我的程序?

我的目标是使用 Int 16 指令能够使用箭头键在程序中上下移动,直到我的用户决定按退出键。我是否在循环中使用以下代码读取多个按键并在末尾添加终止条件,或者是否缺少某些内容?

Mov ah,00
int 16
Run Code Online (Sandbox Code Playgroud)

assembly real-mode bios x86-16

3
推荐指数
1
解决办法
8204
查看次数