cltq 在汇编中做什么? [英] What does cltq do in assembly?
问题描述
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 cdqe
的 gas
助记符,记录在: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 中,这通常表示从签名的 int
到 long
的转换.
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&TCWTL
),CBW
(AT&TCBTW
):CDQE
,也以 32 位出现CQO
家族,其符号将RAX
扩展为RDX:RAX
MOVSX
家族,既符号扩展又移动:whatmovsbl指令做什么?
CWDE
(AT&TCWTL
),CBW
(AT&TCBTW
): smaller versions ofCDQE
, also present in 32-bitCQO
family, which sign extendsRAX
intoRDX: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屋!