Assembly 16位x86汇编程序,使用8位内存存储的颜色变量将蓝色绘制到屏幕时遇到问题?
以下代码在Xubuntu 16.04上编译并运行良好,使用 bashshell中的这些命令Assembly 16位x86汇编程序,使用8位内存存储的颜色变量将蓝色绘制到屏幕时遇到问题?,assembly,memory,nasm,dos,x86-16,Assembly,Memory,Nasm,Dos,X86 16,以下代码在Xubuntu 16.04上编译并运行良好,使用 bashshell中的这些命令 nasm blue.asm-fbin-oblue.com dosbox./blue.com-退出 我遇到的问题是在20号线上 mov-al,1;字节[蓝色] 如果我用这个来代替呢 mov al,字节[蓝色] 该程序在屏幕上绘制了一种勃艮第酒,而不是蓝色。它通常适用于使用1,这是此处8位调色板中的颜色代码 这是完整的代码,如果还有其他问题,请随时告诉我 org 00h bits 16 sec
nasm blue.asm-fbin-oblue.com
dosbox./blue.com-退出
我遇到的问题是在20号线上
mov-al,1;字节[蓝色]
如果我用这个来代替呢
mov al,字节[蓝色]
该程序在屏幕上绘制了一种勃艮第酒,而不是蓝色。它通常适用于使用1,这是此处8位调色板中的颜色代码
这是完整的代码,如果还有其他问题,请随时告诉我
org 00h
bits 16
section .data
blue: db 1
section .text
MAIN:
AsyncKeyInput:
mov al, 13h
int 10h
; Segment a000h
mov ax, 0a000h
mov es, ax
; Offset 0
xor di, di
mov al, 1;byte [blue]
; Looplength (320*200)/2 = 7d00
mov cx, 7d00h
hplot:
mov [ es: di], al ;set pixel to colour
inc di ;move to next pixel
loop hplot
mov ah, 1 ;Get the State of the keyboard buffer
int 16h ;key press
jz AsyncKeyInput ;if not zero then exit the program
;exit program
mov eax, 1
mov ebx, 0
int 0x80
ret
该问题的解决方案是为com程序将程序段前缀正确设置为
org 100h
。下面是更正后的代码
org 100h
bits 16
section .data
blue: db 1h
section .text
MAIN:
AsyncKeyInput:
mov al, 13h
int 10h
; Segment a000h
mov ax, 0a000h
mov es, ax
; Offset 0
xor di, di
xor eax, eax
mov al, byte [blue]
; Looplength (320*200)/2 = 7d00
mov cx, 7d00h
hplot:
mov [ es: di], al ;set pixel to colour
inc di ;move to next pixel
loop hplot
mov ah, 1 ;Get the State of the keyboard buffer
int 16h ;key press
jz AsyncKeyInput ;if not zero then exit the program
;text mode
mov ax, 0003h
int 10h
ret
org 00
或org 0x100
int0x80
是一个退出系统调用而不是DOS退出,COM程序应该只与ret
一起工作,我认为它是org00
,但这是默认的对吗?那就不用申报了?它应该是0x100
?区别是什么,堆栈大小正确吗?DOS COM程序的偏移量为0x100。变量的所有偏移量都将相对于0x100,而不是0x00,我的更改为-是。100h或0x100当然是一样的。两者都是十六进制。如果将其设置为0,则blue
等变量的所有偏移都将相对于0原点。对于.COM程序,当DOS加载它们时,它们实际上是在段中的偏移量0x100处启动的。0x00和0x100之间的字节是相同的。还有一个(大)问题。COM没有任何部分,这只是另一个小问题,以mov al,13h
int 10h
开始代码不是设置13h gfx模式的正确方法。您还必须将ah
设置为零(“设置gfx模式服务”),在dosbox下,您很幸运,在加载COM后,他们的DOS在ah
中保留零。因此mov ax,13h
是加载AH=0,AL=0x13的正确方法。(然后标签AsyncKeyInput
可能放置不好,导致每次重新初始化gfx模式)。@Ped7g“COM没有任何部分,很简单,如果你每次都重新启用图形模式,然后将其绘制为蓝色,它就会闪烁。如果您没有设置ah
,它将被设置为后面的int16h
中的某个值,并且您正在调用int10h
的随机服务,al=13h
。。。出于某种原因,你很幸运,没有把某件东西称为真正的碰撞/破坏,所以它对你“有效”,但它根本不正确。如果不想闪烁,您需要更改主循环逻辑,可能只需设置一次图形模式。关于linux:在linux(AFAIK)下,没有简单的方法可以直接访问视频ram,最简单的方法之一可能是加载一些类似于SDL的库(可能选择具有最简单API的库),然后从ASM调用它,或者甚至创建简单的C++骨架来为ASM代码(初始化视频、控制器等)编写环境,在C/C++中封装任何OS/HW的数据,然后在纯ASM中执行纯算法,并编写到已经准备好的缓冲区中以生成GFX。