0
mov  rax,QWORD PTR [rbp-0x10]

mov  eax,DWORD PTR [rax]

add  eax,0x1

mov  DWORD PTR [rbp-0x14], eax

Next lines written in C, compiled with GCC in GNU/Linux environment.

Assembly code is for int b = *a + 1;.

...

int a = 5;

int* ptr = &a;

int b = *a + 1;

dereferencing whats in address of a and adding 1 to that. After that, store under new variable.

What I don`t understand is second line in that assembly code. Does it mean that I cut QWORD to get the DWORD(one part of QWORD) and storing that into eax?

Since the code is few lines long, I would love that to be broke into step by step sections just to confirm that I`m on right track, also, to figure out what that second line does. Thank you.

  • The assembly you posted is just a fragment. For example, the instruction that initialised `a` to `5` is missing. If you could post the whole function, an explanation might be easier to produce. – fuz Oct 16 '17 at 13:14
  • int* is 8 bytes in x64 code, thus QWORD. Dereferencing the pointer produces int, 4 bytes in x64 code, thus DWORD. – Hans Passant Oct 16 '17 at 13:23
  • @HansPassant I believe that that answer could satisfy my need. Thank you very much. – Learn on hard way Oct 16 '17 at 13:30
  • 1
    How does the `int b = *a + 1;` line even compile? The expression `*a` isn't valid because `a` has type `int`. Did you make a typo, and should it be `int b = *ptr + 1;` instead? – BeeOnRope Oct 16 '17 at 16:32

2 Answers2

1

What I don`t understand is second line in that assembly code. Does it mean that I cut QWORD to get the DWORD(one part of QWORD) and storing that into eax?

No, the 2nd line dereferences it. There's no splitting up of a qword into two dword halves. (Writing EAX zeros the upper 32 bits of RAX).

It just happens to use the same register that it was using for the pointer, because it doesn't need the pointer anymore.

Compile with optimizations enabled; it's much easier to see what's happening if gcc isn't storing/reloading all the time. (How to remove "noise" from GCC/clang assembly output?)

int foo(int *ptr) {
    return *ptr + 1;
}

    mov     eax, DWORD PTR [rdi]
    add     eax, 1
    ret

(On Godbolt)

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Thank you, but I was looking on explanation on those lines above. – Learn on hard way Oct 16 '17 at 13:31
  • You answer the wrong question. He wants to dereference pointer which is casted from the integer value – 0___________ Oct 16 '17 at 14:48
  • 1
    @PeterJ_01 I think he's answering the right question, but it's a bit confusing because there is no _dereference_ at all in the posted C code (in fact, it does not compile) - but there is deferencing evident in the asm. There is also no casting, not sure what you're looking at there? – BeeOnRope Oct 16 '17 at 16:33
  • @BeeOnRope: heh, I just wanted to answer the bolded question about "cutting" a qword, and didn't look at the C carefully. I was implicitly assuming what you pointed out on the question, that the OP meant `*ptr` not `*a`. Updated my example to use `ptr` as the variable name! – Peter Cordes Oct 17 '17 at 01:03
-1
int a = 5;

int* ptr = &a;

int b = *a + 1;

your example is an undefined behaviour as you dereference the integer value converted to the pointer (in this case 5) and it will not compile at all as this conversion has the unknown type.

To make it work you need to cast it first. `int b = *(int *)a + 1;

https://godbolt.org/g/Yo8dd1

Explanation of your assembly code:

line 1: loads rax with the value of a (in this case 5) line 2: dereferences this value (reads from the address 5 so probably you will get the segmentation fault). this code loads from the stack only because you use the -O0 option.

Community
  • 1
  • 1
0___________
  • 60,014
  • 4
  • 34
  • 74