assembly - 使用 ES 寄存器会出现错误

标签 assembly x86 nasm x86-16 cpu-registers

我正在将程序从 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中不起作用?

最佳答案

其他答案的替代方案

由于0xA000是一个常量,因此可以这样定义它,然后将其用作立即值而不是内存操作数。为了使这种方法起作用,您需要将常量放置在中间寄存器中,然后将其移动到段寄存器。

<小时/>

您可以将startaddr定义为常量(而不是包含段值的内存地址)。您可以使用EQU创建常量(立即值)。更改此行:

startaddr   dw  0a000h  ;start of video memory   

startaddr   EQU  0a000h  ;start of video memory   

既然你不能MOV直接将立即数传递给 DSESSS,将值放入中间寄存器,然后将其移至段寄存器。所以这段代码:

mov es, startaddr       ;put segment address in es

可能是:

mov ax, startaddr
mov es, ax              ;put segment address in es

注意:如果创建可读代码,并且您使用上述方法 - 我建议将 startaddr 重命名为 STARTADDR。全大写标识符的约定向读者表明它是一个常量(立即值)而不是一个变量。

<小时/>

您遇到的其他错误与 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 COMEXE 程序

关于assembly - 使用 ES 寄存器会出现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34121971/

相关文章:

c - 学习反汇编

c - 深入 assembly

x86 - 如何知道一个中断是硬件中断还是cpu异常

performance - 将fpu切换为单精度

assembly - ARM assembly 中的 movw 和 movt

arrays - 如何在 x86 程序集中正确索引数组

winapi - 如何让这两行在 cmd 控制台中的不同行上打印

linux - 为什么 main() 函数的 argc 在 ESP+4 而不是 ESP+0?

assembly - 使用 NASM 程序集将 16 位十进制数转换为其他基数

nasm - 无效段覆盖