1

I am writing inline assembly and I came across a error that I don't know how to fix. This part of the code raises an error. It is supposed to add "i" to "source" and "array" addresses, and copy the contents of the byte at "source" to "array".

int main()
{
    char* _source = new char [1];
    _source[0] = 1;
    char* array = new char[1];
    unsigned int i = 0;
    __asm volatile (
        "mov eax, $[source] \n\t"
        "add eax, $[i] \n\t"
        "mov bh, [eax] \n\t"
        "mov ecx, $[array] \n\t"
        "add ecx, $[i] \n\t"
        "mov [ecx], bh \n\t"
        :
        : "r" "source" (_source), "r" "array" (array), "r" "i" (i)
        : "eax", "bh", "ecx", "memory"
    );
}

This code is executed using gcc.

gcc -m32 -masm=intel -o test.cpp 

And the errors that show up

C:\Users\geish\AppData\Local\Temp\ccMCDck3.s:34: Error: invalid operands (.text and *UND* sections) for `+'
C:\Users\geish\AppData\Local\Temp\ccMCDck3.s:35: Error: invalid operands (.text and *UND* sections) for `+'
C:\Users\geish\AppData\Local\Temp\ccMCDck3.s:37: Error: invalid operands (.text and *UND* sections) for `+'
C:\Users\user\AppData\Local\Temp\ccMCDck3.s:38: Error: invalid operands (.text and *UND* sections) for `+'
C:\Users\user\AppData\Local\Temp\ccMCDck3.s:56: Error: invalid operands (.text and *UND* sections) for `+'
C:\Users\user\AppData\Local\Temp\ccMCDck3.s:57: Error: invalid operands (.text and *UND* sections) for `+'
C:\Users\user\AppData\Local\Temp\ccMCDck3.s:59: Error: invalid operands (.text and *UND* sections) for `+'
C:\Users\user\AppData\Local\Temp\ccMCDck3.s:60: Error: invalid operands (.text and *UND* sections) for `+'
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Salty 27
  • 91
  • 6
  • @UlrichEckhardt code was edited to reproduce the error – Salty 27 May 09 '21 at 14:58
  • It's `%[source]` not `$[source]`. Look at the compiler's asm output and you'll see the literal `$[source]` there in the text, not replaced with an operand the compiler picked. https://godbolt.org/z/4c5a78v9v – Peter Cordes May 09 '21 at 15:02
  • Also, your asm is missing a `"memory"` clobber - you only tell the compiler about pointer inputs, not the memory you read/write. (It's implicitly `volatile` because you don't have any output operands, but that would be a good idea if you don't want to tell the compiler about the memory input and output specifically.) [How can I indicate that the memory \*pointed\* to by an inline ASM argument may be used?](https://stackoverflow.com/q/56432259). I edited your question to fix that separate problem from what you were asking about. – Peter Cordes May 09 '21 at 15:04

1 Answers1

1

Your use of named operands is wrong in a few ways. Instead of "r" "source" (_source), you should specify the operand as: [source] "r" (_source), where [source] specifies its name, _source is the C variable, and "r" is the constaint to use. And you should access the operand with %[source], not $[source].

interjay
  • 107,303
  • 21
  • 270
  • 254
  • https://stackoverflow.com/tags/inline-assembly/info has links to guides and stuff which show basic syntax. Also, looking at the compiler's asm output is often very helpful to see exactly what the assembler is choking on: https://godbolt.org/z/YPznd58s5. I'm still not sure what exactly the error message is complaining about with adding two addresses; possibly `$` as a symbol and `source` as another symbol, implicitly adding by using outside and inside brackets. – Peter Cordes May 09 '21 at 15:17