What are the meanings of callq command parameters?

23 篇文章 0 订阅
22 篇文章 0 订阅

https://stackoverflow.com/questions/56122039/what-are-the-meanings-of-callq-command-parameters

 

It's just call. Use Intel-syntax disassembly if you want to be able to look up instructions in the Intel/AMD manuals.

The q operand-size suffix does technically apply (it pushes a 64-bit return address and treats RIP as a 64-bit register), but there's no way to override it with instruction prefixes. i.e. calll and callw aren't encodeable in 64-bit mode, so it's just annoying that some AT&T syntax tools show it as callq instead of call. This of course applies to retq as well.

Different tools are different in 32 vs. 64-bit mode. (Godbolt)

  • gcc -S: always call/ret. Nice.
  • clang -S: callq/retq and calll/retl. At least it's consistently annoying.
  • objdump -d: callq/retq (explicit 64-bit) and call/ret (implicit for 32-bit). Inconsistent and kinda dumb because 64-bit has no choice of operand-size, but 32-bit does. (Not a useful choice, though: callw truncates EIP to 16 bits.)

    Although on the other hand, the default operand size (without a REX.W prefix) for most instructions in 64-bit mode is still 32. But add $1, (%rdi) needs an operand-size suffix; the assembler won't pick 32-bit for you if nothing implies one. OTOH, push is implicitly pushq, even though pushw $1 and pushq $1 are both encodeable (and usable in practice) in 64-bit mode.


From Intel's instruction-set ref manual (linked above):

For a near call absolute, an absolute offset is specified indirectly in a general-purpose register or a memory location (r/m16, r/m32, or r/m64). The operand-size attribute determines the size of the target operand (16, 32 or 64 bits). When in 64-bit mode, the operand size for near call (and all near branches) is forced to 64-bits.

for rel32 ... As with absolute offsets, the operand-size attribute determines the size of the target operand (16, 32, or 64 bits). In 64-bit mode the target operand will always be 64-bits because the operand size is forced to 64-bits for near branches.

In 32-bit mode, you can encode a 16-bit call rel16 that truncates EIP to 16 bits, or a call r/m16 that uses an absolute 16-bit address. But as the manual says, the operand-size is fixed in 64-bit mode.

 

//------------------------------------------------------问题原始点-------------------------------------------------------//

https://segmentfault.com/q/1010000019148085/a-1020000019199743

请问反汇编代码中callq 23<main+0x13>的含义:
第一个参数我只知道是push 23,保存返回地址,第二个<main+0x19>应该是fun函数地址,但是fun函数应该是在main的前面啊,怎么地址反而比main的地址还高?

C代码:

#include <stdio.h>

void fun(int a)
{
}
 
int main()
{
    int a = 1234;
    fun(a);
}

objdump -D main.o main.asm
反汇编代码main.asm如下

0000000000000000 <fun>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   89 7d fc                mov    %edi,-0x4(%rbp)
   7:   90                      nop
   8:   5d                      pop    %rbp
   9:   c3                      retq   

000000000000000a <main>:
   a:   55                      push   %rbp
   b:   48 89 e5                mov    %rsp,%rbp
   e:   48 83 ec 10             sub    $0x10,%rsp
  12:   c7 45 fc 03 00 00 00    movl   $0x3,-0x4(%rbp)
  19:   8b 45 fc                mov    -0x4(%rbp),%eax
  1c:   89 c7                   mov    %eax,%edi
  1e:   e8 00 00 00 00          callq  23 <main+0x19>
  23:   b8 00 00 00 00          mov    $0x0,%eax
  28:   c9                      leaveq 
  29:   c3                      retq   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值