somewhere between input to as and ld farting the executable, bad things are done to jmp/call operands. I was just starting to experiment with assembly too :(. Observe [helmet@BuffyRox helmet]$ echo 'main(){__asm__("call 0x10");}'>temp.c&&gcc -o temp temp.c 2>/dev/null&&gdb -q temp (gdb) disas main Dump of assembler code for function main: 0x8048398 <main>: push %ebp 0x8048399 <main+1>: mov %esp,%ebp 0x804839b <main+3>: call 0x10 0x80483a0 <main+8>: leave 0x80483a1 <main+9>: ret etc. the 0x10 gdb shows is rolled out absolute value. If this code was hit, %eip would get 0x10. It is supposed to call the code 10 bytes ahead (at main+18) A quick glance at an instructions reference tells me bytes 2-5 of the call instruction are the 32 bit displacement value.. (gdb) x/1dw main+4 0x804839c <main+4>: -134513552 (gdb) print 0x80483a0 $1 = 134513568 (gdb) so something's translating the 0x10 to neg(%eip - 0x10) I tried this on suse 6.3 and it's working the way I expected, and "smashing the stack for fun and profit" by aleph one tells me it should work the way I say too :) helmet@exodus:~ > echo 'main(){__asm__("call 0x10");}'>temp.c&&gcc -o temp temp.c 2>/dev/null&&gdb -q temp (gdb) disas main Dump of assembler code for function main: 0x80483b0 <main>: push %ebp 0x80483b1 <main+1>: mov %esp,%ebp 0x80483b3 <main+3>: call 0x80483c8 <__do_global_ctors_aux+8> 0x80483b8 <main+8>: mov %ebp,%esp 0x80483ba <main+10>: pop %ebp 0x80483bb <main+11>: ret it's using a binutils package advertised as binutils-2.9.1.0.25-46
call absolute_number in as for ia32 may be either absolute call, or call .+the number gcc itself avoids generating such calls. Use a symbol defined to 0x10 in call if you want to make absolute call, use .+number if you want to do a %eip relative call.