user2672982
user2672982

Reputation: 21

x86 assembly language homework prob

I need help with a homework problem. I am supposed to figure out what the value of edx will be after this code runs.

0x40106e    <main+30>:      mov    $0x1,%edx
0x401073    <main+35>:      mov    $0x8,%ecx
0x401078    <main+40>:      test   %ecx,%ecx
0x40107a    <main+42>:      jg     0x40107e <main+46>
0x40107c    <main+44>:      jmp    0x40108a <main+58>
0x40107e    <main+46>:      lea    (%ecx,%ecx,1),%eax
0x401081    <main+49>:      lea    (%eax,%edx,1),%eax
0x401084    <main+52>:      lea    0xffffffff(%eax),%edx
0x401087    <main+55>:      dec    %ecx
0x401088    <main+56>:      jmp    0x401078 <main+40>
0x40108a    <main+58>:      // endpoint

Since it is homework I don't really want to know the answer as much as how to figure it out. I was having trouble with figuring out the loop, but I think I got it. I think the test %ecx,%ecx loops until %ecx is decremented to 0. Is that right? What's really getting me is all the lea stuff. I cannot figure out what that is doing.

Upvotes: 1

Views: 1130

Answers (2)

user35443
user35443

Reputation: 6403

As icktoofay explained, the lea instruction is going to set the edx register to eax - 1. Let's go through the whole code, step by step.

The first two lines are moving immediate values to registers, so edx is made equal to 1 and ecx is set to 8.

The test instruction is at the start of the loop here and together with the instruction immediately after it states the condition for the execution of the loop. The test instruction affects quite a few flags, but as the conditional jump is jg, we'll only focus on ZF, OF and SF. jg branches only if ZF=0 while SF=OF. Now

  • ZF will be zero until ECX!=0
  • OF will always be zero and the same applies for SF, as 8 is greater than zero in two's complement (more precisely the most significant bit of 8 is 0).

The first lea instruction sets eax to 2*ecx. The second and the last leas add eax to edx and decrement it. Finally, ecx is decremented and instruction pointer is set to the start of the loop.

Written out symbolically:

sum(8, n = 1, n*2 -1) + 1

Upvotes: 1

icktoofay
icktoofay

Reputation: 128993

You're right about the test and jg; it does indeed loop until ecx is zero.

lea

I'm not very familiar with AT&T syntax, so I'll use Intel syntax (which I find more intuitive) instead. I hope it's still intelligible. (One of the main differences is that Intel syntax puts the destination first.)

Some instructions let you load a value from an address:

mov eax, [esi]  ; load a DWORD from the address in ESI

You can change these to add offsets:

mov eax, [esi + 4]  ; load a DWORD from four bytes after the address in ESI

Certain combinations of registers, scales, and offsets are allowed:

mov eax, [esi + ecx * 4 + 16]  ; load a DWORD from (ECX * 4 + 16) bytes after the
                               ; address in ESI

This is rather convenient; you don't need to calculate the effective address manually.

lea stands for “Load Effective Address”. Essentially, it lets you do something like this:

lea eax, [esi + ecx * 4 + 16]

Rather than loading the value in memory at that location, it just computes the address; in other words:

EAX = ESI + ECX * 4 + 16

The lea instruction above assembles to 4 bytes. In contrast, the most obvious way to me:

mov eax, ecx
shl eax, 2
add eax, esi
add eax, 16

…assembles to 14 bytes.

Upvotes: 1

Related Questions