user1706538
user1706538

Reputation: 641

Two lines in assembly that don't make any sense together

I have to read through some randomly generated assembly and enter some proper input to get to the end without calling the explode_bomb function. The problem is there are two lines which seem to directly contradict each other, and I'm worried that my assignment may in fact be impossible due to random generation.

Here is the full code:

 08048d1b <phase_2>:
 8048d1b:       55                      push   %ebp
 8048d1c:       89 e5                   mov    %esp,%ebp
 8048d1e:       56                      push   %esi
 8048d1f:       53                      push   %ebx
 8048d20:       83 ec 30                sub    $0x30,%esp
 8048d23:       8d 45 e0                lea    0xffffffe0(%ebp),%eax
 8048d26:       89 44 24 04             mov    %eax,0x4(%esp)
 8048d2a:       8b 45 08                mov    0x8(%ebp),%eax
 8048d2d:       89 04 24                mov    %eax,(%esp)
 8048d30:       e8 42 04 00 00          call   8049177 <read_six_numbers>
 8048d35:       83 7d e0 00             cmpl   $0x0,0xffffffe0(%ebp)
 8048d39:       79 05                   jns    8048d40 <phase_2+0x25>
 8048d3b:       e8 f5 03 00 00          call   8049135 <explode_bomb>
 8048d40:       bb 01 00 00 00          mov    $0x1,%ebx
 8048d45:       8d 75 e0                lea    0xffffffe0(%ebp),%esi
 8048d48:       89 d8                   mov    %ebx,%eax
 8048d4a:       03 44 9e fc             add    0xfffffffc(%esi,%ebx,4),%eax
 8048d4e:       39 04 9e                cmp    %eax,(%esi,%ebx,4)
 8048d51:       74 05                   je     8048d58 <phase_2+0x3d>
 8048d53:       e8 dd 03 00 00          call   8049135 <explode_bomb>
 8048d58:       83 c3 01                add    $0x1,%ebx
 8048d5b:       83 fb 06                cmp    $0x6,%ebx
 8048d5e:       75 e8                   jne    8048d48 <phase_2+0x2d>
 8048d60:       83 c4 30                add    $0x30,%esp
 8048d63:       5b                      pop    %ebx
 8048d64:       5e                      pop    %esi
 8048d65:       5d                      pop    %ebp
 8048d66:       c3                      ret  

The lines in question are 8048d4a and 8048d4e. Being that this is in 2's compliment, the first number is a -4, the second number is my first input (does this ever even change to my second and third?), and the third will be whatever iteration of the loop we're on, as will the fourth.

Now comparing these values in direct sequence basically means I'm comparing a number to itself - 4, right? How could I ever feasibly pass that test?

Thank you for your assistance.

Upvotes: 0

Views: 1322

Answers (2)

ninjalj
ninjalj

Reputation: 43688

mov    $0x1,%ebx                        ; i = 1
lea    0xffffffe0(%ebp),%esi            ; ESI = address of array of 6 numbers
mov    %ebx,%eax                        
add    0xfffffffc(%esi,%ebx,4),%eax     ; add to element
cmp    %eax,(%esi,%ebx,4)

add    0xfffffffc(%esi,%ebx,4),%eax

The above instruction is accessing an element of an array. This is called SIB addressing in x86, for Scale, Index, Base. There is also an Offset component. The array is based at an address determined by the Base register (EBX here) plus an offset (-4 here). The element number is at the Index register (ESI here). The size of each element is determined by the Scale (4 here).

lea    0xffffffe0(%ebp),%esi            ; ESI = address of array of 6 numbers

If you look further up, you see how the address of the array is moved into %ESI. The array is a local variable, located 32 bytes below the frame pointer (when using a frame pointer, local variables, including arrays, are addressed as an offset from the frame pointer)

add    0xfffffffc(%esi,%ebx,4),%eax

So this instruction accesses a "virtual" array that starts 4 bytes before the real array. This is because the loop index starts at 1, but the element accessed is 0, so using the "virtual array" everything falls into place.

mov    $0x1,%ebx                        ; i = 1
lea    0xffffffe0(%ebp),%esi            ; ESI = address of array of 6 numbers
mov    %ebx,%eax                        
add    0xfffffffc(%esi,%ebx,4),%eax     ; add to element i-1
cmp    %eax,(%esi,%ebx,4)               ; compare against element i

Upvotes: 0

Necrolis
Necrolis

Reputation: 26171

my AT&T syntax isn't the best, but it seems its doing:

ADD EAX,[ESI + EBX * 4 - 4]
CMP EAX,[ESI + EBX * 4]

aka, its comparing the sum of the previous and some counter to the current entry. see this for reference, specifically:

Example:
Intel Syntax
instr   foo,segreg:[base+index*scale+disp]
mov     eax,[ebx+20h]
add     eax,[ebx+ecx*2h
lea     eax,[ebx+ecx]
sub     eax,[ebx+ecx*4h-20h]
AT&T Syntax
instr   %segreg:disp(base,index,scale),foo
movl    0x20(%ebx),%eax
addl    (%ebx,%ecx,0x2),%eax
leal    (%ebx,%ecx),%eax
subl    -0x20(%ebx,%ecx,0x4),%eax

As for why its doing it this way, well it appears to be an optimization to avoid a register spill or the alternative of decrementing the array index then incrementing it.

Upvotes: 2

Related Questions