cltq 在汇编中做什么? [英] What does cltq do in assembly?

查看:24
本文介绍了cltq 在汇编中做什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

0x0000000000400553 <main+59>:   mov    -0x4(%rbp),%eax
0x0000000000400556 <main+62>:   cltq   
0x0000000000400558 <main+64>:   shl    $0x3,%rax
0x000000000040055c <main+68>:   mov    %rax,%rdx

其实我的程序很简单:

5   int main(int argc, char *argv[]) { 
6     int i = 0;
7     while(environ[i]) {
8       printf("%s
", environ[i++]);
9     }
10    return 0;

但是汇编输出很长:

Dump of assembler code for function main:
0x0000000000400518 <main+0>:    push   %rbp
0x0000000000400519 <main+1>:    mov    %rsp,%rbp
0x000000000040051c <main+4>:    sub    $0x20,%rsp
0x0000000000400520 <main+8>:    mov    %edi,-0x14(%rbp)
0x0000000000400523 <main+11>:   mov    %rsi,-0x20(%rbp)
0x0000000000400527 <main+15>:   movl   $0x0,-0x4(%rbp)
0x000000000040052e <main+22>:   jmp    0x400553 <main+59>
0x0000000000400530 <main+24>:   mov    -0x4(%rbp),%eax
0x0000000000400533 <main+27>:   cltq   
0x0000000000400535 <main+29>:   shl    $0x3,%rax
0x0000000000400539 <main+33>:   mov    %rax,%rdx
0x000000000040053c <main+36>:   mov    0x2003e5(%rip),%rax        # 0x600928 <environ@@GLIBC_2.2.5>
0x0000000000400543 <main+43>:   lea    (%rdx,%rax,1),%rax
0x0000000000400547 <main+47>:   mov    (%rax),%rdi
0x000000000040054a <main+50>:   addl   $0x1,-0x4(%rbp)
0x000000000040054e <main+54>:   callq  0x400418 <puts@plt>
0x0000000000400553 <main+59>:   mov    -0x4(%rbp),%eax
0x0000000000400556 <main+62>:   cltq   
0x0000000000400558 <main+64>:   shl    $0x3,%rax
0x000000000040055c <main+68>:   mov    %rax,%rdx
0x000000000040055f <main+71>:   mov    0x2003c2(%rip),%rax        # 0x600928 <environ@@GLIBC_2.2.5>
0x0000000000400566 <main+78>:   lea    (%rdx,%rax,1),%rax
0x000000000040056a <main+82>:   mov    (%rax),%rax
0x000000000040056d <main+85>:   test   %rax,%rax
0x0000000000400570 <main+88>:   jne    0x400530 <main+24>
0x0000000000400572 <main+90>:   mov    $0x0,%eax
0x0000000000400577 <main+95>:   leaveq 
0x0000000000400578 <main+96>:   retq   
End of assembler dump.

我不明白的是这个块:

0x000000000040052e <main+22>:   jmp    0x400553 <main+59>
0x0000000000400530 <main+24>:   mov    -0x4(%rbp),%eax
0x0000000000400533 <main+27>:   cltq   
0x0000000000400535 <main+29>:   shl    $0x3,%rax
0x0000000000400539 <main+33>:   mov    %rax,%rdx
0x000000000040053c <main+36>:   mov    0x2003e5(%rip),%rax        # 0x600928 <environ@@GLIBC_2.2.5>
0x0000000000400543 <main+43>:   lea    (%rdx,%rax,1),%rax
0x0000000000400547 <main+47>:   mov    (%rax),%rdi
0x000000000040054a <main+50>:   addl   $0x1,-0x4(%rbp)
0x000000000040054e <main+54>:   callq  0x400418 <puts@plt>
0x0000000000400553 <main+59>:   mov    -0x4(%rbp),%eax
0x0000000000400556 <main+62>:   cltq   
0x0000000000400558 <main+64>:   shl    $0x3,%rax
0x000000000040055c <main+68>:   mov    %rax,%rdx
0x000000000040055f <main+71>:   mov    0x2003c2(%rip),%rax        # 0x600928 <environ@@GLIBC_2.2.5>
0x0000000000400566 <main+78>:   lea    (%rdx,%rax,1),%rax
0x000000000040056a <main+82>:   mov    (%rax),%rax
0x000000000040056d <main+85>:   test   %rax,%rax
0x0000000000400570 <main+88>:   jne    0x400530 <main+24>

推荐答案

助记符

cltq 是 Intel cdqegas 助记符,记录在:https://sourceware.org/binutils/docs/as/i386_002dMnemonics.html

cltq is the gas mnemonic for Intel's cdqe as documented at: https://sourceware.org/binutils/docs/as/i386_002dMnemonics.html

助记符是:

  • 将 Long 转换为 Quad (cltq):AT&T 风格
  • 将双倍扩展为四倍扩展 (cdqe):英特尔
  • Convert Long To Quad (cltq): AT&T-style
  • Convert Double to Quad Extend (cdqe): Intel

术语:

  • quad(又名四字)== 8 字节
  • long (AT&T) == 双字 (Intel) == 4 字节

这是少数几个 GAS 名称与 Intel 版本非常不同的指令之一.as 接受助记符,但像 NASM 这样的 Intel 语法汇编器可能只接受 Intel 名称.

This is one of the few instructions whose GAS name is very different from the Intel version. as accepts either mnemonic, but Intel-syntax assemblers like NASM may only accept the Intel names.

效果

它符号将 4 个字节扩展为 8 个字节,在 2 的补码中意味着:

It sign extends 4 bytes into 8 bytes, which in 2's complement means that for:

  • 负数,高4字节的位必须设置为1
  • 正数,它们必须设置为 0

在 C 中,这通常表示从签名的 intlong 的转换.

In C, that usually represents a cast from signed int to long.

示例:

mov $0123456700000001, %rax  # eax=1, high bytes of rax=garbage
cltq
# %rax == $0000 0000 0000 0001

mov $-1, %eax   # %rax = 0000 0000 FFFF FFFF
cltq
# %rax == $FFFF FFFF FFFF FFFF == qword $-1

此指令仅适用于 64 位.

This instruction is only available on 64-bits.

还要考虑以下说明:

  • CWDE (AT&T CWTL), CBW (AT&T CBTW):CDQE,也以 32 位出现
  • CQO 家族,其符号将RAX 扩展为RDX:RAX
  • MOVSX 家族,既符号扩展又移动:whatmovsbl指令做什么?
  • CWDE (AT&T CWTL), CBW (AT&T CBTW): smaller versions of CDQE, also present in 32-bit
  • CQO family, which sign extends RAX into RDX:RAX
  • MOVSX family, which both sign extends and moves: what does movsbl instruction do?

GitHub 上带有断言的最小可运行示例:

Minimal runnable examples on GitHub with assertions:

C 示例

GCC 4.9.3 发出它:

GCC 4.9.3 emits it:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    int i = strtol(argv[1], (char **)NULL, 16);;
    long int l = i;
    printf("%lx
", l);
}

编译和反汇编:

gcc -ggdb3 -std=c99 -O0 a.c
objdump -S a.out

包含:

    int main(int argc, char **argv) {
  ...
    long int l2 = i;
  400545:       8b 45 fc                mov    -0x4(%rbp),%eax
  400548:       48 98                   cltq   
  40054a:       48 89 45 f0             mov    %rax,-0x10(%rbp)

行为是:

$ ./a.out 0x80000000
ffffffff80000000
$ ./a.out 0x40000000
40000000

这篇关于cltq 在汇编中做什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆