1
                    201036:    push   %rbp
                    201037:    push   %rbx
                    201038:    sub    $0x28,%rsp
                    20103c:    mov    %rsp,%rsi
                    20103f:    callq  2014a5 <read_input>
                    201044:    cmpl   $0x0,(%rsp)
                    201048:    jne    201051 <func_2+0x1b>
                    20104a:    cmpl   $0x1,0x4(%rsp)
                    20104f:    je     201056 <func_2+0x20>
                    201051:    callq  20146f <wrong_input>
                    201056:    mov    %rsp,%rbp
                    201059:    lea    0x4(%rsp),%rbx
                    20105e:    add    $0x18,%rbp
                    201062:    mov    -0x2(%rbx),%eax
                    201065:    add    -0x4(%rbx),%eax
                    201068:    cmp    %eax,(%rbx)
                    20106a:    je     201071 <func_2+0x3b>
                    20106c:    callq  20146f <wrong_input>
                    201071:    add    $0x2,%rbx
                    201075:    cmp    %rbp,%rbx
                    201078:    jne    201062 <func_2+0x2c>
                    20107a:    add    $0x28,%rsp
                    20107e:    pop    %rbx
                    20107f:    pop    %rbp
                    201080:    retq  

Well, if I break it into lines:

mov    %rsp,%rbp : puts value of rsp into rbp
lea    0x4(%rsp),%rbx : put "0x4*rsp" into rbx. (*rsp = address of or rsp)
add    $0x15,%rbp : adds the integer that at "0x15" to rbp and saves the sum in 
                                                              rbp.

mov    -0x2(%rbx),%eax : moves the value that inside of ??? to eax
add    -0x4(%rbx),%eax : adds the value that inside of ??? to eax as saves the sum 
                                                                           in eax.

cmp    %eax,(%rbx): compares eax with rbx.

well, I can't really understand what "0x4(%rsp)" means, what the minus in "-0x2(%rbx)" and "-0x4(%rbx)" means..

I am trying to connect the dots here. It seems like a loop, that increases rbx or eax and then compares them.. I don't really get it though.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
NoobCoder
  • 513
  • 3
  • 18
  • 1
    related: [A couple of questions about \[base + index\*scale + disp\]](https://stackoverflow.com/q/27936196) / [How does "mov (%ebx,%eax,4),%eax" work?](https://stackoverflow.com/q/14900343) / [Using LEA on values that aren't addresses / pointers?](https://stackoverflow.com/a/46597375) describes using LEA for plain math. – Peter Cordes Dec 24 '20 at 21:40

1 Answers1

2

... I can't really understand what "0x4(%rsp)" means, what the minus in "-0x2(%rbx)" and "-0x4(%rbx)" means..

Those numbers are to be added to the value between the parenthesis, the number is a displacement component.

In 0x4(%rsp), the true address becomes the value in the %RSP register plus 4.
In -0x2(%rbx), the true address becomes the value in the %RBX register minus 2.

e.g. If in mov -0x2(%rbx),%eax the %RBX register holds 100002 then the %EAX register receives the dword stored at memory address 100000.

e.g. If in lea 0x4(%rsp),%ebx the %RSP register holds 100000 then the %EBX register receives the value 100004.


[code was added]

Now that you've added more code, we can try to figure out how the loop might work.

           mov    %rsp,%rsi
           callq  2014a5 <read_input>
           cmpl   $0x0,(%rsp)
           jne    201051 <func_2+0x1b>
           cmpl   $0x1,0x4(%rsp)
           je     201056 <func_2+0x20>
201051:    callq  20146f <wrong_input>

201056:    mov    %rsp,%rbp
           lea    0x4(%rsp),%rbx
           add    $0x18,%rbp

201062:    mov    -0x2(%rbx),%eax
           add    -0x4(%rbx),%eax
           cmp    %eax,(%rbx)
           je     201071 <func_2+0x3b>
           callq  20146f <wrong_input>
201071:    add    $0x2,%rbx
           cmp    %rbp,%rbx
           jne    201062 <func_2+0x2c>

(-) It's unsolvable

In order to avoid that first callq to wrong_input, the first 8 bytes at (%rsp) need to be:

%rsp        %rbx
v           v
00,00,00,00,01,00,00,00
      -----------
+++++++++++ ===========

But then the first iteration of the loop will fail and do that second callq to wrong_input because:

-----------    mov -0x2(%rbx),%eax    --> 0x00010000
+++++++++++    add -0x4(%rbx),%eax    --> 0x00010000 + 0x00000000
===========    cmp %eax,(%rbx)        --> 0x00010000 <> 0x00000001

(+) Think Fibonacci

If we only consider the loop part, then we can find a sequence of integers that will pass. Here they are:

65536, 131073, 327683, 851976, 2228245, 5832759, 144

You need to look at it when stored in memory:

            first                                                 last
%rsp        %rbx                     -->                          %rbx  %rbp
v           v                                                     v     v
00,00,01,00,01,00,02,00,03,00,05,00,08,00,0D,00,15,00,22,00,37,00,59,00,90,00
      -----------                                           -----------
+++++++++++ ===========                               +++++++++++ ===========

Do notice that the loop reads one word beyond the end in %rbp, therefore the input is actually six and a half dword integers!

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • @NoobCoder Because it's a `LEA` instruction, it's the address itself that is stored in the `%RBX` register. No loading from memory involved! If `%RSP` is 0x2020 then `%RBX` receives just the value 0x2024. – Sep Roland Dec 24 '20 at 16:47
  • What do you mean by "the true address becomes the value"? I can't really understand what "lea 0x4(%rsp),%rbx" does.. Does it go to the address of RSP, adds 4, then goes to the new address, and gets the value of it inside of RBX? or does it actually puts the address, like "0x0120" inside of RBX as the value? – NoobCoder Dec 24 '20 at 16:51
  • yes I know that this is the purpose of LEA. But what about the mov? As you mentioned in your example. Will it mov the value inside of the address? – NoobCoder Dec 24 '20 at 16:53
  • 2
    @NoobCoder An instruction that uses parenthesis refers to some memory location. Once all the address components are put together we have the *true address*. Then the instruction takes over. If it's `LEA` we just use the value of the address, if it's `MOV`we read or write something from or to memory. – Sep Roland Dec 24 '20 at 16:57
  • @NoobCoder Your code snippet does not have a loop! For that you would need some kind of jump instruction, most likely a conditional jump below the `CMP` instruction. – Sep Roland Dec 24 '20 at 16:59
  • yes, I do have have a conditional jump, I just did not write it here. It's still quite confusing for me to understand what does this loop do. I mean I always trying to compare it to other language like C or JAVA and "translate" it but I can't understand what is going on here. It jumps right back to the -0x2(%rbx),%eax – NoobCoder Dec 24 '20 at 17:08
  • @NoobCoder Wasn't there a `push %rbp` also before this snippet? – Sep Roland Dec 24 '20 at 17:12
  • I have added the full code. My goal here is to find the right input (which are 6 integers). I did find that the first one must be "1" because of the first CMP to 0x1. But then it starts to loop and I could not find the formula that it goes by. – NoobCoder Dec 24 '20 at 17:29