美文网首页
从汇编来看 C 语言之变量

从汇编来看 C 语言之变量

作者: 蓝笔头 | 来源:发表于2021-07-12 14:25 被阅读0次

汇编语言(机器语言)中没有变量的概念,一切操作都是直接对地址进行。

前置知识

例子:

#include <stdio.h>

int main(int argc, char *argv[]) {
    int a = 10;
    int *pa = &a;
    printf("a = %d\n", a);
    printf("&a = %p\n", &a);

    printf("pa = %p\n", pa);
    printf("&pa = %p\n", &pa);
    return 0;
}

printf("a = %d\n", a); 代码行打上断点。

通过 disass /m 进行进行反汇编。

Breakpoint 1, main (argc=2, argv=0x7fffffffec38) at /tmp/tmp.lskJd4a8xb/main.c:6
6       printf("a = %d\n", a);
(gdb) i line 3
Line 3 of "/tmp/tmp.lskJd4a8xb/main.c" starts at address 0x5555555551c0 <main> and ends at 0x5555555551cf <main+15>.
(gdb) i line 5
Line 5 of "/tmp/tmp.lskJd4a8xb/main.c" starts at address 0x5555555551d6 <main+22> and ends at 0x5555555551de <main+30>.
(gdb) disass /m 0x5555555551c0,+30
Dump of assembler code from 0x5555555551c0 to 0x5555555551de:
3   int main(int argc, char *argv[]) {
   0x00005555555551c0 <main+0>: push   %rbp
   0x00005555555551c1 <main+1>: mov    %rsp,%rbp
   0x00005555555551c4 <main+4>: sub    $0x20,%rsp
   0x00005555555551c8 <main+8>: mov    %edi,-0x14(%rbp)
   0x00005555555551cb <main+11>:    mov    %rsi,-0x20(%rbp)

4       int a = 10;
   0x00005555555551cf <main+15>:    movl   $0xa,-0x4(%rbp)

5       int *pa = &a;
   0x00005555555551d6 <main+22>:    lea    -0x4(%rbp),%rax
   0x00005555555551da <main+26>:    mov    %rax,-0x10(%rbp)

End of assembler dump.

由上述汇编代码(AT&T 格式)可知,-0x4(%rbp) 表示变量 a-0x10(%rbp) 表示变量 pa

进程的堆栈由高地址向低地址扩展。

因为要进行内存对齐,而 -0x4(%rbp) - 0x8 不能整除 8,所以要补位 4,因此 pa 的地址为 -0x10(%rbp)

0x4 + 0x8 + 0x4 = 0x10

通过 i r rbp rsp 打印堆栈寄存器信息。

(gdb) i r rbp rsp
rbp            0x7fffffffeb50   0x7fffffffeb50
rsp            0x7fffffffeb30   0x7fffffffeb30

控制台输出:

/tmp/tmp.lskJd4a8xb/cmake-build-debug/test nfs
a = 10
&a = 0x7fffffffeb4c
pa = 0x7fffffffeb4c
&pa = 0x7fffffffeb40

0x7fffffffeb4c = 0x7fffffffeb50 - 0x4 = -0x4(%rbp) = 变量 a
0x7fffffffeb40 = 0x7fffffffeb50 - 0x10 = -0x10(%rbp) = 变量 pa


leamov 指令】介绍

leaload effective address) 指令可以用来将一个内存地址直接赋给目的操作数。
例如:lea eax,[ebx+8] 就是将 ebx+8 这个值直接赋给 eax,而不是把 ebx+8 处的内存地址里的数据赋给 eax

mov 指令则恰恰相反,例如:mov eax,[ebx+8] 则是把内存地址为 ebx+8 处的数据赋给 eax

上面的汇编指令格式为 Intel 格式。

AT&TIntel 格式中的源操作数和目标操作数的位置正好相反。

  • Intel 汇编格式中,目标操作数在源操作数的左边
  • 而在 AT&T 汇编格式中,目标操作数在源操作数的右边

gdb 命令查看信息命令:

(gdb) i r rbp rsp
rbp            0x7fffffffeb50   0x7fffffffeb50
rsp            0x7fffffffeb30   0x7fffffffeb30
(gdb) p &a
$10 = (int *) 0x7fffffffeb4c
(gdb) p &pa
$11 = (int **) 0x7fffffffeb40
(gdb) x /32xb $rsp
0x7fffffffeb30: 0x38    0xec    0xff    0xff    0xff    0x7f    0x00    0x00
0x7fffffffeb38: 0x90    0x50    0x55    0x55    0x02    0x00    0x00    0x00
0x7fffffffeb40: 0x4c    0xeb    0xff    0xff    0xff    0x7f    0x00    0x00
0x7fffffffeb48: 0x00    0x00    0x00    0x00    0x0a    0x00    0x00    0x00
(gdb) p a
$12 = 10
(gdb) p pa
$13 = (int *) 0x7fffffffeb4c
(gdb) x /16xb $rsp
0x7fffffffeb30: 0x38    0xec    0xff    0xff    0xff    0x7f    0x00    0x00
0x7fffffffeb38: 0x90    0x50    0x55    0x55    0x02    0x00    0x00    0x00

参考

相关文章

  • 从汇编来看 C 语言之变量

    汇编语言(机器语言)中没有变量的概念,一切操作都是直接对地址进行。 前置知识 例子: 在 printf("a = ...

  • C语言10- C语言与汇编

    20:C语言与汇编 20.1:调用约定之汇编 x86调用约定: cdecl:参数从右往左依次入栈,调用者栈平衡(C...

  • C语言到汇编-变量

    变量,类似于汇编中的标号,例如: 这段代码中的year 就是一个标号,它实际上指的是一个长度为2个字节(dw)的内...

  • C语言编程优势,基础超实用C语言格式字符大全

    C语言的局部变量是可以覆盖的,汇编的所有变量都是全局的,C语言不仅仅效率高,而且因为局部变量的不可见性所以更可靠。...

  • c语言if语句逆向分析

    来分析一下c语言if语句直接上代码 下面是对应的汇编代码,汇编代码是从vs2013上面复制的 先来分析一下变量j和...

  • C语言简单实现面向对象思想

    C语言和C++都会经过汇编,生成汇编代码,在汇编代码的阶段,是分辨不出是C语言还是C++语言的。在早期C++还没有...

  • 2. 指令集对CPU的意义

    汇编语言与c语言等高级语言的差异 汇编难写,c好写 汇编无可移植性,c语言有一定的可移植性,Java等高级语言移植...

  • Linux入门第6天-Linux发展史及安装入门

    机器语言>汇编语言>高级语言(C语言、C++) 汇编语言:1.难移植 交叉编译:cross compile ker...

  • 8、运算符

    C语言语句:C语言的编译器通过语句生成对应的汇编代码,从而使得程序可以进行,可以从两个方面来看,分别是语句的组成部...

  • 详解C语言和C++最大的区别,附带新手学习建议

    首先,我们来看看C语言与C++的概念: 1. C语言是一种计算机程序设计语言,它既具有高级语言的特点,又具有汇编语...

网友评论

      本文标题:从汇编来看 C 语言之变量

      本文链接:https://www.haomeiwen.com/subject/torrpltx.html