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.
... 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>
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
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!