c - GCC inline assembler using memory references -
i'm trying write inline assembly instruction load variable contents of register using pointer variable instead of direct reference.
the code using direct reference works fine , looks this:
int x; int *y = &x; int z = 1; __asm__ __volatile__ ("mov %%edx, %0;"::"r"(z):); __asm__ __volatile__ ("mov %0, %%edx;":"=r" (x)::); printf("\n%x\n", x);
disasm:
0x000000000040052d <+0>: push %rbp 0x000000000040052e <+1>: mov %rsp,%rbp 0x0000000000400531 <+4>: sub $0x10,%rsp 0x0000000000400535 <+8>: lea -0x10(%rbp),%rax 0x0000000000400539 <+12>: mov %rax,-0x8(%rbp) 0x000000000040053d <+16>: movl $0x1,-0xc(%rbp) 0x0000000000400544 <+23>: mov -0xc(%rbp),%eax 0x0000000000400547 <+26>: mov %edx,%eax 0x0000000000400549 <+28>: mov %eax,%edx 0x000000000040054b <+30>: mov %eax,-0x10(%rbp) 0x000000000040054e <+33>: mov -0x10(%rbp),%eax 0x0000000000400551 <+36>: mov %eax,%esi 0x0000000000400553 <+38>: mov $0x4005f4,%edi 0x0000000000400558 <+43>: mov $0x0,%eax 0x000000000040055d <+48>: callq 0x400410 <printf@plt> 0x0000000000400562 <+53>: mov $0x0,%eax 0x0000000000400567 <+58>: leaveq 0x0000000000400568 <+59>: retq
and outputs 1 expected
the pointer version looks this:
int x; int *y = &x; int z = 1; __asm__ __volatile__ ("mov %%edx, %0;"::"r"(z):); __asm__ __volatile__ ("mov (%0), %%edx;":"+r" (y)::); //or __asm__ __volatile__ ("mov %[mem], %%edx":[mem] "=m" (y)::); printf("\n%x\n", x);
disasm:
0x000000000040052d <+0>: push %rbp 0x000000000040052e <+1>: mov %rsp,%rbp 0x0000000000400531 <+4>: sub $0x10,%rsp 0x0000000000400535 <+8>: lea -0x10(%rbp),%rax 0x0000000000400539 <+12>: mov %rax,-0x8(%rbp) 0x000000000040053d <+16>: movl $0x1,-0xc(%rbp) 0x0000000000400544 <+23>: mov -0xc(%rbp),%eax 0x0000000000400547 <+26>: mov %edx,%eax 0x0000000000400549 <+28>: mov -0x8(%rbp),%edx 0x000000000040054c <+31>: mov -0x10(%rbp),%eax 0x000000000040054f <+34>: mov %eax,%esi 0x0000000000400551 <+36>: mov $0x4005f4,%edi 0x0000000000400556 <+41>: mov $0x0,%eax 0x000000000040055b <+46>: callq 0x400410 <printf@plt> 0x0000000000400560 <+51>: mov $0x0,%eax 0x0000000000400565 <+56>: leaveq 0x0000000000400566 <+57>: retq
this prints non-deterministic integer every time (i.e bb524b90 15979050). when run in gdb prints same integer (ffffe2f0) every time, doesn't change based on value of z. have idea causes this?
i getting output reg, not input, notice argument positioning
"mov %0, %%edx;":"=r" (x)::
you're confused input/output terminology.
an output operand output from asm
statement, into register chosen compiler (for "=r"
case).
when use "=m"
, compiler make %0
memory operand.
or if used "=a"
, %0
%eax
, , compiler assume value of c variable x
in %eax
.
in at&t syntax, destination operand last operand. think know this, think have input/output backwards.
Comments
Post a Comment