Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

operand generation of CALL instruction on x86-64 AMD

Following is the output of objdump of a sample program,

080483b4 <display>:
 80483b4:       55                      push   %ebp
 80483b5:       89 e5                   mov    %esp,%ebp
 80483b7:       83 ec 18                sub    $0x18,%esp
 80483ba:       8b 45 0c                mov    0xc(%ebp),%eax
 80483bd:       89 44 24 04             mov    %eax,0x4(%esp)
 80483c1:       8d 45 fe                lea    0xfffffffe(%ebp),%eax
 80483c4:       89 04 24                mov    %eax,(%esp)
 80483c7:       e8 ec fe ff ff          call   80482b8 <strcpy@plt>
 80483cc:       8b 45 08                mov    0x8(%ebp),%eax
 80483cf:       89 44 24 04             mov    %eax,0x4(%esp)
 80483d3:       c7 04 24 f0 84 04 08    movl   $0x80484f0,(%esp)
 80483da:       e8 e9 fe ff ff          call   80482c8 <printf@plt>
 80483df:       c9                      leave
 80483e0:       c3                      ret

080483e1 <main>:
 80483e1:       8d 4c 24 04             lea    0x4(%esp),%ecx
 80483e5:       83 e4 f0                and    $0xfffffff0,%esp
 80483e8:       ff 71 fc                pushl  0xfffffffc(%ecx)
 80483eb:       55                      push   %ebp
 80483ec:       89 e5                   mov    %esp,%ebp
 80483ee:       51                      push   %ecx
 80483ef:       83 ec 24                sub    $0x24,%esp
 80483f2:       c7 44 24 04 f3 84 04    movl   $0x80484f3,0x4(%esp)
 80483f9:       08
 80483fa:       c7 04 24 0a 00 00 00    movl   $0xa,(%esp)
 8048401:       e8 ae ff ff ff          call   80483b4 <display>
 8048406:       b8 00 00 00 00          mov    $0x0,%eax
 804840b:       83 c4 24                add    $0x24,%esp
 804840e:       59                      pop    %ecx
 804840f:       5d                      pop    %ebp
 8048410:       8d 61 fc                lea    0xfffffffc(%ecx),%esp

What i need to understand, is in main we see the following at address - 8048401, call 80483b4 , however the machine code is - e8 ae ff ff ff. I see that CALL instruction is E8 but how is the address of function 80483b4 getting decoded to FFFFFFAE? I did a lot of search in google but it did not return anything. Can Anyone please explain?

like image 252
Samir Baid Avatar asked Feb 24 '12 21:02

Samir Baid


People also ask

What is x86 call instruction?

The CALL instruction performs two operations: It pushes the return address (address immediately after the CALL instruction) on the stack. It changes EIP to the call destination. This effectively transfers control to the call target and begins execution there.

How many operands does the x86 add assembly instruction have?

An x86 instruction can have zero to three operands. Operands are separated by commas (,) (ASCII 0x2C). For instructions with two operands, the first (lefthand) operand is the source operand, and the second (righthand) operand is the destination operand (that is, source->destination).

Is x86 instruction set?

x86 is a family of complex instruction set computer (CISC) instruction set architectures initially developed by Intel based on the Intel 8086 microprocessor and its 8088 variant.

How many registers may be used to pass function parameters in x86-64 and what are they?

On x86-64 Linux, the first six function arguments are passed in registers %rdi , %rsi , %rdx , %rcx , %r8 , and %r9 , respectively. The seventh and subsequent arguments are passed on the stack, about which more below. The return value is passed in register %rax . The full rules more complex than this.


3 Answers

E8 is the operand for "Call Relative", meaning the destination address is computed by adding the operand to the address of the next instruction. The operand is 0xFFFFFFAE, which is negative 0x52. 0x808406 - 0x52 is 0x80483b4.

Most disassemblers helpfully calculate the actual target address rather than just give you the relative address in the operand.

Complete info for x86 ISA at: http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-2a-manual.html

like image 192
Michael Avatar answered Nov 11 '22 06:11

Michael


Interesting question. I've had a look at Intel's documentation and the E8 opcode is CALL rel16/32. 0xffffffae is actually a 32-bit two's complement signed integer equal to -82 decimal; it is a relative address from the byte immediately after the opcode and its operands.

If you do the math you can see it checks out:

0x8048406 - 82 = 0x80483b4

This puts the instruction pointer at the beginning of the display function.

like image 33
spencercw Avatar answered Nov 11 '22 05:11

spencercw


Near calls are typically IP-relative -- meaning, the "address" is actually an offset from the instruction pointer. In such case, EIP points to the next instruction (so its value is 8048406). Add ffffffae (or -00000052 in two's complement) to it, and you get 80483b4.

Note that all this math is 32-bit. You're not doing any 64-bit operations here (or your registers would have Rs instead of Es in their names, and the addresses would be much longer).

like image 39
cHao Avatar answered Nov 11 '22 06:11

cHao