使用 ES 寄存器会出错
Using ES register gives errors
我正在将程序从 EMU8086 环境转换到 NASM。组装时 NASM 给出这些错误:
system\kernel.asm:14: error: invalid combination of opcode and operands
system\kernel.asm:20: error: invalid combination of opcode and operands
system\kernel.asm:28: error: invalid combination of opcode and operands
我的代码是:
jmp start
;==============================
;Draws a horiz and vert line
;==============================
startaddr dw 0a000h ;start of video memory
colour db 1
;==============================
start:
mov ah,00
mov al,19
int 10h ;switch to 320x200 mode
;=============================
horiz:
mov es, startaddr ;put segment address in es *** 1st ERROR HERE!
mov di, 32000 ;row 101 (320 * 100)
add di, 75 ;column 76
mov al,colour
mov cx, 160 ;loop counter
hplot:
mov es:[di],al ;set pixel to colour *** 2nd ERROR HERE!
inc di ;move to next pixel
loop hplot
vert:
mov di, 16000 ;row 51 (320 * 50)
add di, 160 ;column 161
mov cx, 100 ;loop counter
vplot:
mov es:[di],al ; *** 3rd ERROR HERE!
add di, 320 ;mov down a pixel
loop vplot
我已经标记了错误的行。为什么这在 NASM 中不起作用?
没有直接加载es
或ds
的处理器指令。您必须加载数据寄存器,然后将其移动到段寄存器
mov ax,0A000h
mov es,ax
在 NASM 中,您必须使用方括号来检索 startaddr 处的值。
写:
mov es, [startaddr] ;put segment address in es
另外 NASM 希望您在这些括号之间写段覆盖:
mov [es:di],al ;set pixel to colour
另一个 NASM 无法为您检测到的错误是您认为如何检索 colour 变量。您还应该在此处使用 []:
mov al, [colour]
替代其他答案
因为0xA000是一个常量,所以可以这样定义它,然后将它用作立即值而不是内存操作数。为了使这种方法起作用,您需要将常量放在中间寄存器中,然后将其移动到段寄存器。
您可以将startaddr定义为常量(不是包含段值的内存地址)。您可以使用 EQU 创建常量(立即值)。更改此行:
startaddr dw 0a000h ;start of video memory
到
startaddr EQU 0a000h ;start of video memory
因为你不能MOV立即值到DS、ES和SS 直接,你把值放到一个中间寄存器,然后把它移到段寄存器。所以这段代码:
mov es, startaddr ;put segment address in es
可能是:
mov ax, startaddr
mov es, ax ;put segment address in es
注意:如果创建可读代码,并且您使用上述方法 - 我建议将 startaddr 重命名为 STARTADDR。所有大写标识符的约定表明 reader 它是一个常量(立即值)而不是变量。
您遇到的其他错误与 EMU8086 和 NASM 之间的语法差异有关。这些行:
mov es:[di],al ;set pixel to colour
和
vplot:
mov es:[di],al
需要写在方括号内的段。它们应该如下所示:
mov [es:di],al ;set pixel to colour
和
vplot:
mov [es:di],al
我强烈建议您阅读 NASM documentation 关于生成 DOS COM 和 EXE 程序
我正在将程序从 EMU8086 环境转换到 NASM。组装时 NASM 给出这些错误:
system\kernel.asm:14: error: invalid combination of opcode and operands
system\kernel.asm:20: error: invalid combination of opcode and operands
system\kernel.asm:28: error: invalid combination of opcode and operands
我的代码是:
jmp start
;==============================
;Draws a horiz and vert line
;==============================
startaddr dw 0a000h ;start of video memory
colour db 1
;==============================
start:
mov ah,00
mov al,19
int 10h ;switch to 320x200 mode
;=============================
horiz:
mov es, startaddr ;put segment address in es *** 1st ERROR HERE!
mov di, 32000 ;row 101 (320 * 100)
add di, 75 ;column 76
mov al,colour
mov cx, 160 ;loop counter
hplot:
mov es:[di],al ;set pixel to colour *** 2nd ERROR HERE!
inc di ;move to next pixel
loop hplot
vert:
mov di, 16000 ;row 51 (320 * 50)
add di, 160 ;column 161
mov cx, 100 ;loop counter
vplot:
mov es:[di],al ; *** 3rd ERROR HERE!
add di, 320 ;mov down a pixel
loop vplot
我已经标记了错误的行。为什么这在 NASM 中不起作用?
没有直接加载es
或ds
的处理器指令。您必须加载数据寄存器,然后将其移动到段寄存器
mov ax,0A000h
mov es,ax
在 NASM 中,您必须使用方括号来检索 startaddr 处的值。
写:
mov es, [startaddr] ;put segment address in es
另外 NASM 希望您在这些括号之间写段覆盖:
mov [es:di],al ;set pixel to colour
另一个 NASM 无法为您检测到的错误是您认为如何检索 colour 变量。您还应该在此处使用 []:
mov al, [colour]
替代其他答案
因为0xA000是一个常量,所以可以这样定义它,然后将它用作立即值而不是内存操作数。为了使这种方法起作用,您需要将常量放在中间寄存器中,然后将其移动到段寄存器。
您可以将startaddr定义为常量(不是包含段值的内存地址)。您可以使用 EQU 创建常量(立即值)。更改此行:
startaddr dw 0a000h ;start of video memory
到
startaddr EQU 0a000h ;start of video memory
因为你不能MOV立即值到DS、ES和SS 直接,你把值放到一个中间寄存器,然后把它移到段寄存器。所以这段代码:
mov es, startaddr ;put segment address in es
可能是:
mov ax, startaddr
mov es, ax ;put segment address in es
注意:如果创建可读代码,并且您使用上述方法 - 我建议将 startaddr 重命名为 STARTADDR。所有大写标识符的约定表明 reader 它是一个常量(立即值)而不是变量。
您遇到的其他错误与 EMU8086 和 NASM 之间的语法差异有关。这些行:
mov es:[di],al ;set pixel to colour
和
vplot:
mov es:[di],al
需要写在方括号内的段。它们应该如下所示:
mov [es:di],al ;set pixel to colour
和
vplot:
mov [es:di],al
我强烈建议您阅读 NASM documentation 关于生成 DOS COM 和 EXE 程序