汇编:[SI + CX] =地址大小的不可能组合

时间:2013-12-26 14:39:41

标签: assembly operating-system nasm interrupt cpu-registers

所以,今天我尝试使用一个简单的功能为我的开发中的操作系统创建一个库:在屏幕上打印字符。要使用此函数,我只需将字符串地址推送到堆栈并调用它(字符串必须以0x00字节结束)。以下是该函数的源代码:

__print:                        ;Print string that is terminated with a 0x00 to screen

__print_prepare:
    pop si                  ;SI Register = String Address
    mov ah, 0x0E                ;0x0E Function = Print Character on screen
    mov bx, 0x0F                ;Background = Black, CharColor = White
    xor cx, cx              ;Counter = 0

__print_check:
    push byte [cx + si]         ;Push character to the stack
    or byte [cx + si], byte [cx + si]   ;Check if the byte equals 0x00
    jz __print_exit             ;If true then exit
    jmp __print_main            ;Else print the character

__print_main:
    pop al                  ;Store the byte in the AL Register
    int 0x10                ;Call interupt 0x10 = BIOS Interupt
    jmp __print_next            ;Continue to next character

__print_next:
    inc cx                  ;Increment CX Register by one for next character = Counter
    jmp __print_check           ;Check authenticity of character

__print_exit:
    ret

无论何时我尝试汇编源代码,都会出现以下nasm错误:

  

def_os_lib.asm:10:错误:操作码和操作数的无效组合

     

def_os_lib.asm:11:错误:操作码和操作数的无效组合

     

def_os_lib.asm:16:错误:操作码和操作数的无效组合

此外,在某些情况下,即我以ELF格式编译它时,它会提示此错误:

  

def_os_lib.asm:10:错误:地址大小的不可能组合

     

def_os_lib.asm:11:错误:地址大小的不可能组合

我用于nasm(bin)的命令是:

  

nasm -f bin def_os_lib.asm

我用于nasm(elf64)的命令是:

  

nasm -f elf64 def_os_lib.asm

我刚刚开始组装,我知道我为我的知识做了太大的一步。我只是想深入一点。

谢谢大家的帮助。我已经用你的建议纠正了错误,完成了源代码。这是新代码:

__print:                        ;Print string that is terminated with a 0x00 to screen

__print_prepare:
    pop si                  ;SI Register = String Address
    xor bx, bx              ;Counter = 0

__print_check:
    push bx                 ;Save BX
    xor ax, ax              ;AX = 0
    add bx, si              ;BX = Address of the character
    mov al, byte [bx]           ;AL = Character
    pop bx                  ;Restore BX
    push ax                 ;Save character
    or ax, ax               ;Check if the byte equals 0x00
    jz __print_exit             ;If true then exit
    jmp __print_main            ;Else print the character

__print_main:
    pop ax                  ;Store the byte in the AL Register
    push bx                 ;Save BX
    mov bx, 0x0F                ;Background = Black, CharColor = White
    mov ah, 0x0E                ;0x0E Function = Print Character on screen
    int 0x10                ;Call interupt 0x10 = BIOS Interupt
    jmp __print_next            ;Continue to next character

__print_next:
    pop bx                  ;Restore BX
    inc bx                  ;Increment CX Register by one for next character = Counter
    jmp __print_check           ;Check authenticity of character

__print_exit:
    ret

2 个答案:

答案 0 :(得分:4)

  

按字节[cx + si]

cx cannot be used in adressing under real mode

  

或byte [cx + si],byte [cx + si]

在x86中,一条指令通常不能有两个内存操作数。你需要使用寄存器作为中间人。

答案 1 :(得分:2)

您只能将[BX或BP]与[SI或DI]结合使用;不允许使用AX,DX或CX。

你不能推送/弹出一个字节POP AL所以任何字节大小的参数都将被视为无效。