Pregunta

Compiler: gcc 4.7.1, 32bit, ubuntu

Here's an example:

    int main(void)
    {
        unsigned int mem = 0;

        __asm volatile
        (
            "mov ebx, esp\n\t"
            "mov %0, [ds : ebx]\n\t"
            : "=m"(mem)
        );

        printf("mem = 0x%08x\n", mem);

        return 0;
    }

gcc -masm=intel -o app main.c

Assembler messages: invalid use of register!

As I know, ds and ss point to the same segment. I don't know why I can't use [ds : ebx] logical address for addressing.

¿Fue útil?

Solución

Your code has two problems:

One: the indirect memory reference should be:

mov %0, ds : [ebx]

That is, with the ds out of the brackets.

Two: A single instruction cannot have both origin and destination in memory, you have to use a register. The easiest way would be to indicate =g that basically means whatever, but in your case it is not possible because esp cannot be moved directly to memory. You have to use =r.

Three: (?) You are clobbering the ebx register, so you should declare it as such, or else do not use it that way. That will not prevent compilation, but will make your code to behave erratically.

In short:

  unsigned int mem = 0;
  __asm volatile
  (
    "mov ebx, esp\n\t"
    "mov %0, ds : [ebx]\n\t"
    : "=r"(mem) :: "ebx"
  );

Or better not to force to use ebx, let instead the compiler decide:

  unsigned int mem = 0, temp;
  __asm volatile
  (
    "mov %1, esp\n\t"
    "mov %0, ds : [%1]\n\t"
    : "=r"(mem) : "r"(temp)
  );

BTW, you don't need the volatile keyword in this code. That is used to avoid the assembler to be optimized away even if the output is not needed. If you write the code for the side-effect, add volatile, but if you write the code to get an output, do not add volatile. That way, if the optimizing compiler determines that the output is not needed, it will remove the whole block.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top