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

Popular posts from this blog

ios - MKAnnotationView layer is not of expected type: MKLayer -

ZeroMQ on Windows, with Qt Creator -

unity3d - Unity SceneManager.LoadScene quits application -