版权声明:darboy https://blog.csdn.net/weixin_38428827/article/details/84900181
[学习]程序的机器级表示总结记录
用GCC生成一段汇编文件
GCC的安装就不说了。
用到的命令有gcc -S test.c
,会再当前目录下生成.s的汇编文件。
test.c 如下:
#include <stdio.h>
#include <Windows.h>
#define TCP 1
void plus_opreater(int, int);
int main()
{
int a = 1;
int b = 2;
plus_opreater(a,b);
system("pause");
return 0;
}
void plus_opreater(int a, int b)
{
printf("2 number add together is %d \n",(a+b));
}
test.s 如下:
.file "test.c" //“.”前缀是这个的不用看,是用来指导汇编器及链接器的指令
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "pause\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main: //函数体
LFB21:
.cfi_startproc
pushl %ebp //将寄存器%ebp的内容压入程序栈 ebp是帧指针,esp是栈指针,pop是将数据弹出程序栈
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp //movl是传送双字,movb是传送字节,movw是传送字
.cfi_def_cfa_register 5
andl $-16, %esp //$这个符号是立即数的意思,操作数有三种,立即数(immediate),寄存器(register),存储器(memory)
subl $32, %esp //sub是减去的意思,将栈指针减去立即数32,add是增加的意思
call ___main
movl $1, 28(%esp) //28(%esp),28是立即数,%esp是寄存器,整体就是28+%esp的值来寻址
movl $2, 24(%esp) //mov类指令是将源操作数的值复制到目的操作数中,第一个是源操作数,第二个是目的操作数
movl 24(%esp), %eax
movl %eax, 4(%esp)
movl 28(%esp), %eax
movl %eax, (%esp)
call _plus_opreater
movl $LC0, (%esp)
call _system
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE21:
.section .rdata,"dr"
LC1:
.ascii "2 number add together is %d \12\0"
.text
.globl _plus_opreater
.def _plus_opreater; .scl 2; .type 32; .endef
_plus_opreater:
LFB22:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $24, %esp
movl 8(%ebp), %edx
movl 12(%ebp), %eax
addl %edx, %eax
movl %eax, 4(%esp)
movl $LC1, (%esp)
call _printf
nop
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE22:
.ident "GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"
.def _system; .scl 2; .type 32; .endef
.def _printf; .scl 2; .type 32; .endef
栈是一个数据结构,可以添加或者删除值,不过要遵循“后进先出的”原则,通过push操作将数据压入栈,通过pop删除数据,它具有一个属性:弹出的值永远是最近压入栈而仍然在栈中的值。栈可以实现为一个数组,总是从数组的一段插入或删除元素。这一端称为栈顶。
C语言中的“指针”就是地址。间接引用指针就是将该指针放入一个寄存器中。然后再存储器中引用这个寄存器。局部变量通常是保存在寄存器中的,因为寄存器比存储器访问快得多。
算术、逻辑和移位指令
指令 | 描述 |
---|---|
INC D | 加1 |
DEC D | 减1 |
NEG D | 取负 |
NOT D | 取补 |
ADD S,D | 加 |
SUB S,D | 减 |
IMUL S,D | 乘 |
XOR S,D | 异或 |
OR S,D | 或 |
AND S,D | 与 |
SAL k,D | 左移 |
SHL k,D | 左移 |
SAR k,D | 算术右移 |
SHR k,D | 逻辑右移 |