user2056639
user2056639

Reputation: 107

Invalid operand type error

NASM gives the following error message:

> ipl.asm:33: error: invalid operand type

Where the error appears:

    RESB    0x7dfe-$

Here is the code:

        ORG     0x7c00

        JMP     entry

entry:

        MOV     AX,0
        MOV     SS,AX
        MOV     SP,0x7c00
        MOV     DS,AX
        MOV     ES,AX

        MOV     SI,msg
putloop:

        MOV     AL,[SI]
        ADD     SI,1
        CMP     AL,0
        JE      fin
        MOV     AH,0x0e
        MOV     BX,15
        INT     0x10
        JMP     putloop
fin:

        HLT
        JMP     fin

msg:

        DB      0x0a, 0x0a
        DB      "hello, world"
        DB      0x0a
        DB      0

        RESB    0x7dfe-$

        DB      0x55, 0xaa

Upvotes: 2

Views: 4290

Answers (1)

paxdiablo
paxdiablo

Reputation: 882626

It may be because the operand for resb has to be a critical expression. That means it has to be knowable on the first pass of the assembler (a).

What you can do instead is to ensure you only use values already known in the first pass.

First, place a start label at 0x7c00:

          org 0x7c00
start:    jmp entry

Then change the space reservation to define another label and use the difference between them to calculate how many bytes are needed:

marker:   resb 0x1ffe-(marker-start)

What this does is calculate the number of bytes already output (marker-start, both values known before the resb statement) and subtract that from the number of bytes you wanted (0x7dfe - 0x7c00 = 0x01fe). Then it reserves that much space, as shown by the listing output:

0000039 00                       DB      0
000003A <res 000001C4>   marker: RESB    0x01fe-(marker-start)
        * warning: uninitialized space declared in .text section: zeroing
000001FE 55AA                    DB      0x55, 0xaa

You can see the final two bytes are at offset 0x01fe which, given the 0x7c00 base, is actually 0x7dfe as desired.


(a) The reason why your expression is considered unknowable has to do, I think, with the fact that it uses an actual address, which is not necessarily known in pass 1. This is supported by the fact that 0xffff - start will also cause the same error despite the fact it's using a real, already declared, label rather than $.

By instead using an expression like 0xffff - (label1 - label2), the labels themselves may not be known but the difference between them is.

Upvotes: 5

Related Questions