标签: x86-16

推入全栈 8086 组件

令人惊讶的是,PUSH 到完整堆栈的物理结果是什么当为堆栈仅分配 2 个字节 [1 个字] 并 PUSH 三个字,然后将它们弹出到不同的寄存器中时,它完成时没有任何错误当 PUSHing 时,我能说一下堆栈内容吗第二项

这是堆栈段定义:

Stack_segment_name segment para stack
db 2 dup(0) ;define your stack segment
Stack_segment_name ends
Run Code Online (Sandbox Code Playgroud)

这是代码:

Code_segment_name segment
Main_prog PROC FAR

assume     SS:Stack_segment_name,CS:Code_segment_name,DS:Data_segment_name,ES:Data_segment_name

MOV AX,Data_segment_name ; load the starting address of the data
MOV DS,AX ; segment into DS reg.

MOV AX,1715H
MOV BX,1518H
MOV CX,2944H
PUSH AX
PUSH BX
PUSH CX
POP SI 
POP DI  
POP DX



MOV AH,4CH
INT 21H


Main_prog endp
Code_segment_name ends
    end Main_prog
Run Code Online (Sandbox Code Playgroud)

执行代码后:

SI=2944H …
Run Code Online (Sandbox Code Playgroud)

assembly callstack x86-16

2
推荐指数
1
解决办法
2583
查看次数

NASM 引导加载程序中的 jmp $

我试图从Bootloader编写引导加载程序。写的代码是

BITS 16

start:
    mov ax, 07C0h       ; Set up 4K stack space after this bootloader
    add ax, 288     ; (4096 + 512) / 16 bytes per paragraph
    mov ss, ax
    mov sp, 4096

    mov ax, 07C0h       ; Set data segment to where we're loaded
    mov ds, ax


    mov si, text_string ; Put string position into SI
    call print_string   ; Call our string-printing routine

    jmp $           ; Jump here - infinite loop!


    text_string db 'This is my cool …
Run Code Online (Sandbox Code Playgroud)

assembly bios nasm bootloader x86-16

2
推荐指数
1
解决办法
3619
查看次数

Intel 8086:为什么有 4 个内存段

据我了解,8086处理器有4个内存段:堆栈段、代码段、数据段和额外段,以及相应的段寄存器(SS, CS, DS, ES

问题是:“为什么?”
为什么不将数据段和代码段结合起来?
为什么我们需要额外的段?
为什么是4?

我知道这个问题可能听起来很无聊,但我在去年在我的大学进行的一次“微处理器架构”考试中发现了这个问题。

提前致谢。

cpu-architecture cpu-registers x86-16

2
推荐指数
1
解决办法
1361
查看次数

为什么将值 2 添加到 si 只会使索引增加 1?

我是 x86 架构和汇编的初学者,这是一个代码片段,其下面包含步骤。

我知道 si 是源索引,它充当数组的索引。

突出显示的行表明正在向其中添加 2,但答案表明我们仅向上移动索引 1。

我确信我的解释是错误的,如果有人能解释发生了什么,那将会有很大帮助!

汇编新手友好的词汇首选!

在此输入图像描述

x86 assembly x86-16

2
推荐指数
1
解决办法
1759
查看次数

我无法在具有直接内存访问的 8086 程序集中使用中点算法绘制圆

我有一项任务,要求我使形状移动并用颜色改变形状。我一开始就没有成功地画出圆的八分圆。假设使用 Intel 8086 汇编语言,在 DMA 模式下使用 TASM。(模式 19)我在想如果我能完成一个圆圈,我可以给它设置动画并改变形状。我无法弄清楚是算法错误还是代码错误。

.model small
.stack 256

.code 
startaddr   dw  0a000h  ;start of video memory   
color   db  3 
xc dw  160
yc dw 100
r dw  50 ; radius
x dw 0 
y dw 50 ;radius
pk dw 1
temp dw 1

plot macro r1, r2, r3 ;x,y,color
    mov ax, r2
    mov bx, 320
    mul bx
    add ax, r1
    mov di, ax
    mov al, r3
    mov es:[di], al
endm

start:    
  mov ax, yc
  add y, …
Run Code Online (Sandbox Code Playgroud)

assembly tasm x86-16

2
推荐指数
1
解决办法
1335
查看次数

使用 BIOS 例程 INT10h 从变量打印字符

有人知道下面的代码有什么问题吗?

我无法让它按照我想要的方式工作。我只想打印变量的单个字符(字母“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)

assembly bios nasm bootloader x86-16

2
推荐指数
1
解决办法
1531
查看次数

当垂直回扫位被清除时,VGA 卡是否会读取像素缓冲区?

我正在开发一款使用视频模式 13h 的 DOS 游戏。

我一直遇到屏幕撕裂的问题,但直到今天我一直忽略这个问题。我认为修复这将是一个挑战,因为它将涉及延迟像素写入一段精确的时间。但这实际上是一个非常简单的修复。

您所要做的就是等待重新设置 VGA 状态字节的垂直回扫位(位 3),该位在彩色模式下可在端口 0x3da 上使用。

所以我只需要修改这个旧程序,它将我的帧缓冲区写入从 A000:0000 开始的 VGA 像素缓冲区:

WRITE_FRAME PROC

;WRITES ALL 64,000 PIXELS (32,000 WORDS) IN THE FRAME BUFFER TO VIDEO MEMORY

    push es
    push di
    push ds
    push si
    push cx

    mov cx, frame
    mov ds, cx
    xor si, si             ;ds:si -> frame buffer (source)                  

    mov cx, vidMemSeg
    mov es, cx
    xor di, di             ;es:di -> video memory (destination)

    mov cx, (scrArea)/2    ;writing 32,000 words of pixels
    rep movsw …
Run Code Online (Sandbox Code Playgroud)

assembly vga x86-16

2
推荐指数
1
解决办法
1096
查看次数

80286:乘以 10 最快的方法是什么?

要将一个数字乘以 2 的任意倍数,我将对其进行多次移位。

有没有这样的技术可以在更少的周期内将数字乘以 10?

assembly micro-optimization x86-16

2
推荐指数
1
解决办法
1022
查看次数

位移值对 ModRegRm 字节的 Mod 字段有什么影响?

我正在编写一个 8086 汇编器,它接受指令并生成 8086 机器代码。我使用《Intel 8086 用户手册》作为参考。

为了说清楚,我将解释一下情况。假设我想汇编这条指令mov ax, bx。我查手册发现,当 的操作数mov是 2 个 16bit 寄存器时,操作码mov0x89和 来指定操作数(源和目的),mov在这种情况下,后面跟着一个 ModRegRm 字节,指定源以及目的地,在本例中为0xd8。二进制中的该字节 = 11011000.

Mod为2位,Reg、Rm各为3位。所以,Mod = 11,Reg = 011,Rm = 000。这里很简单,但有一些我不明白的地方,那就是寻址模式和位移。

modregrm 表

查看表格和以下三个指令及其机器代码。

mov [bx+0x6], ax ;894706

mov [bx+0xbf],ax ;8987BF00

mov [bx+0xffff],ax ;8947FF

我假设每条指令的位移长度分别为8位、8位、16位,这是否错误?

我认为我是对的,因为它很明显,0x6分别0xbf是 1 字节和0xffff2 字节。

问题是,为什么第二条指令中的MOD字段是10b or 0x02而不是01b or 0x01?应该是0x01因为位移是8bit位移吧?为什么位移量是 16 位,MOD 却0x01在第三条指令中?为什么汇编器忽略其余的位移并仅捕获 1 个字节?

assembly machine-code sign-extension addressing-mode x86-16

2
推荐指数
1
解决办法
932
查看次数

DOS 在运行时插入段地址

我注意到我正在编写的一些代码中存在潜在的错误。

我认为,如果我使用mov ax, seg segment_name,该程序可能是不可移植的,并且只能在特定配置的一台机器上运行,因为加载位置可能因机器而异。

所以我决定在两台运行 DOS 的不同机器上反汇编一个只包含一条指令的程序,我发现问题神奇地解决了。

一号机上的调试输出:0C7A:014C B8BB0C MOV AX,0CBB

二号机器上的调试输出:06CA:014C B80B07 MOV AX,070B

十六进制转储程序后,我发现未更改的字节实际上是B84200.

手动将这些字节插入到程序中会导致mov ax, 0042

那么 PE 格式是否存储对这些指令的引用并在运行时更新它们?

dos relocation portable-executable memory-segmentation x86-16

2
推荐指数
1
解决办法
395
查看次数