首页 文章

使用ES寄存器会出错

提问于
浏览
3

我正在将程序从EMU8086环境转换为NASM . 组装NASM时会出现以下错误:

system \ kernel.asm:14:错误:操作码和操作数system \ kernel.asm的无效组合:20:错误:操作码和操作数system \ kernel.asm的无效组合:28:错误:操作码和操作数的无效组合

我的代码是:

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?

3 回答

  • 3

    其他答案的替代品

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


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

    startaddr   dw  0a000h  ;start of video memory
    

    startaddr   EQU  0a000h  ;start of video memory
    

    由于您不能直接将DS,ES和SS立即赋值为MOV,因此将值放入中间寄存器,然后将其移至段寄存器 . 所以这段代码:

    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 COM和EXE程序

  • 4

    在NASM中,您必须使用方括号来检索startaddr中的值 .

    写:

    mov es, [startaddr]       ;put segment address in es
    

    NASM还希望您在这些括号之间编写段覆盖:

    mov [es:di],al      ;set pixel to colour
    

    NASM无法检测到的另一个错误是您如何检索颜色变量 . 您还应该在这里使用 []

    mov al, [colour]
    
  • 2

    没有处理器指令直接加载 esds . 您必须加载数据寄存器,然后将其移动到段寄存器

    mov ax,0A000h
    mov es,ax
    

相关问题