assemblyx86nasmaddressing-mode

error: invalid operand type when mutiplying by register


I am making a program in x86_64 assembly language and it requires me to offset a memory address by a variable. I am trying to use the * to multiply the address by edx however, I get the following error:

    kernel.asm:23: error: invalid operand type

Why is this happening and how do I fix my problem? Here is my code:

mov edx, 1
mov ebx, 0xb8000+160*edx
inc edx

Solution

  • Thing is that your instruction is invalid, because memory operands are required to be in wrapped in square brackets. Applying this change you would have mov ebx, [0xb8000+160*edx]. Using the Intel/MASM/DOS notation for hexadecimal numbers as NASM also allows, you'd get mov ebx, [0b8000h+160*edx]. This instruction would still be wrong, because the SIB byte of the instruction encoding on x86 ISA only allows scale factors of 2,4 and 8 as described in Table 2-3 of the Intel Manual. 160 is not a valid scale factor. Finally, you want to calculate the address, so better use LEA and not mov: lea ebx, [0b8000h+2/4/8*edx].

    You have to calculate the value with other instructions like MUL, IMUL, SHL or INC to get the resulting value you want.

    For example, you can do the following calculation to position your cursor (with ECX=X and EDX=Y) assuming an 80x25 text mode (using IMUL instead of MUL as suggested in the comments):

    mov ecx, X             ; where X might be [esp+8] or [xpos] or whatever
    mov edx, Y             ; you may not need a register, imul-immediate can load
    ; with inputs in registers
    imul ebx, edx, 160    ; calculate line offset
    lea ebx, [0B8000h + ebx+ecx*2]  ; add column offset and base address
                          ; Now EBX is Y*160+X*2