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

问题描述

限时删除!!

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

实际上我的程序很简单:

In fact my programe is as simple as :

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

但是程序集输出相当长:

But the assembly output is pretty long:

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.

我不明白的是这个障碍:

What I don't understand is this block:

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是英特尔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

助记符是:

  • 将长整数转换为四进制(cltq):AT& T样式
  • 将双倍转换为四倍扩展(cdqe):Intel
  • 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系列,其符号都可以扩展和移动: movsbl指令做什么?/a>

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\n", 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在组装中做什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-07 03:08