c语言到汇编的学习

[内存结构]

C程序通过编译-汇编-连接,最后到可执行文件。载入内存有这几个部分:

text:正文段,存放的是可执行的机器码段

data:存放初始化之后的全局变量和静态变量

bbs:存放未初始化的静态变量和全局变量

heap:堆,由程序员自己分配和释放,程序结束时,操作系统也会释放。

stack: 栈,编译器自动分配,存放函数的参数,局部变量

下图是典型的内存布局图


#include <stdio.h>
#include <stdlib.h>
void foo(int x){printf("hello");}
typedef void(*FunCall)(int);
typedef struct{
FunCall b;
char c;
int a;
}AA;

int main(){
AA aa;
aa.c = ‘s‘;
aa.a = 7;
aa.b = foo;
(*(aa.b))(aa.a);
return 0;
}

这是一个很简单的程序, 使用GCC编译选项编译成AT&T语法的汇编语言

  gcc -S test1.c

下面来分析汇编代码


 1     .file    "test1.c"
2 .section .rodata
3 .LC0:
4 .string "hello"
5 .text
6 .globl foo
7 .type foo, @function
8 foo:
9 .LFB0:
10 .cfi_startproc
11 pushq %rbp
12 .cfi_def_cfa_offset 16
13 movq %rsp, %rbp
14 .cfi_offset 6, -16
15 .cfi_def_cfa_register 6
16 subq $16, %rsp
17 movl %edi, -4(%rbp)
18 movl $.LC0, %eax
19 movq %rax, %rdi
20 movl $0, %eax
21 call printf
22 leave
23 .cfi_def_cfa 7, 8
24 ret
25 .cfi_endproc
26 .LFE0:
27 .size foo, .-foo
28 .globl main
29 .type main, @function
30 main:
31 .LFB1:
32 .cfi_startproc
33 pushq %rbp
34 .cfi_def_cfa_offset 16
35 movq %rsp, %rbp
36 .cfi_offset 6, -16
37 .cfi_def_cfa_register 6
38 subq $16, %rsp
39 movb $115, -8(%rbp)
40 movl $7, -4(%rbp)
41 movq $foo, -16(%rbp)
42 movq -16(%rbp), %rdx
43 movl -4(%rbp), %eax
44 movl %eax, %edi
45 call *%rdx
46 movl $0, %eax
47 leave
48 .cfi_def_cfa 7, 8
49 ret
50 .cfi_endproc
51 .LFE1:
52 .size main, .-main
53 .ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
54 .section .note.GNU-stack,"",@progbits

以点开头的是汇编指示。

指令介绍

寄存器介绍

函数调用

汇编生成

gcc -g -c test.c
objdump -d -M intel -S test.o

c语言到汇编的学习,布布扣,bubuko.com

时间: 2024-10-11 23:02:40

c语言到汇编的学习的相关文章

一个资深C语言工程师说如何学习C语言

谈及C语言,我想凡是学过它的朋友都有这样一种感觉,那就是"让我欢喜让我忧."欢喜的是,C语言功能非常强大.应用广泛,一旦掌握了后,你就可以理直气壮地对他人说"我是电脑高手!",而且以后若是再自学其他语言就显得轻而易举了.忧虑的是,C语言犹如"少林武功"一般博大精深,太难学了.其实就笔者认为C语言并非是"difficult(困难)"的,只要你能理清思路,掌握它的精髓,那么自学C语言是一件非常容易且又其乐无穷的事.今天本人就与大家

汇编入门学习笔记 (六)—— si、di,双重循环

疯狂的暑假学习之  汇编入门学习笔记 (六)-- si.di,双重循环 参考: <汇编语言> 王爽 第7章 1. and和or指令,与[bx+idata] and和or,就不多说了. [bx+idata] 这样写是可以的,某些情况下,比较方便. [bx+idata] 也可以写成 idata[bx] 直接见例子: 把'ABcde' 跟 'fGHig' 都改成大写(ASCII中大写字母与小写字母二进制中,只有第五位不同,大写字母是0,小写字母是1) assume cs:code,ds:data d

汇编入门学习笔记 (八)—— 转移指令

疯狂的暑假学习之  汇编入门学习笔记 (八)--  转移指令 參考: <汇编语言> 王爽 第9章 能够改动ip或者同一时候改动cs和ip的指令统称为转移指令. 8086CPU转移行为分为: 段内转移:仅仅改动ip 段间转移:同一时候改动cs和ip 段内转移按ip改动的范围可分为: 短转移:ip改动范围 -128~127 近转移:ip改动范围 -32768~32767 转移指令分为: 无条件转移指令.如 jmp 条件转移指令 循环指令.如 loop 过程. 中断. 1. offset,nop指令

[易语言]连接ACCESS数据库学习

一.支持库配置 工具-支持库配置-数据库操作支持库 二.添加控件 启动窗口添加控件(数据库连接/记录集/超级列表框) 三.数据库连接 数据库连接1.连接Access ("数据库文件路径", "数据库密码") 例:数据库连接1.连接Access (取运行目录 () + "H:\m.mdb", "") 四.定义变量 .局部变量 索引, 整数型 .局部变量 用户ID, 整数型 .局部变量 日期时间, 文本型 五.例子 .支持库 eD

C语言调用汇编实现字符串对换

1. 前面配置arm交叉编译环境. 2. 配置好qemu-arm C语言代码string-switch.c: #include <stdio.h> #include <stdlib.h> extern void strswp(char *str1, char *str2); int main(void) { char str1[10] = "123456789"; char str2[10] = "abcde"; strswp(str1, s

汇编入门学习笔记 (三) —— 第一个程序

疯狂的暑假学习之  汇编入门学习笔记 (三)-- 第一个程序 参考:<汇编语言> 王爽  第四章 1.一个源程序从写到执行的过程 第一步:编写汇编源程序 第二步:对源程序进行编译连接 第三步:在操作系统中执行 2.源程序 代码: assume cs:first first segment start: mov ax,2 add ax,ax add ax,ax mov ax,4C00H int 21H first ends end start 代码解释: assume .segment.ends

汇编入门学习笔记 (十四)—— 直接定址表

疯狂的暑假学习之  汇编入门学习笔记 (十四)-- 直接定址表 参考: <汇编语言> 王爽 第16章 1. 描述单元长度的标号 普通的标号:a,b assume cs:code code segment a:db 1,2,3,4,5,6,7,8 b:dw 0 start: mov si,offset a mov di,offset b mov ah,0 mov cx,8 s: mov al,cs:[si] add cs:[di],ax inc si loop s mov ax,4c00h in

汇编入门学习笔记 (四)—— [BX] 和 loop指令

疯狂的暑假学习之  汇编入门学习笔记 (四)-- [BX]  和 loop指令 参考:<汇编语言> 王爽 第5章 1.[BX] mov al,[1] 在debug中,会把bs:1 中数据赋给al,但在在masm中不会把bs:1 中数据赋给al,而是把 [1] 认为是 1 赋给al. 如果要实现在debug中的mov al,[1],在masm中就需要[bx] 如: mov bx,1 mov al,[bx] 还可以用 bs:[1] 的方式 如: mov al,bs:[1] 2.loop 循环 要使

汇编入门学习笔记 (七)—— dp,div,dup

疯狂的暑假学习之  汇编入门学习笔记 (七)--  dp,div,dup 参考: <汇编语言> 王爽 第8章 1. bx.si.di.和 bp 8086CPU只有4个寄存器可以用 "[...]" 中进行单元寻址. bp:除了默认的段地址是ss,其他与bx一样. 它们所有正确的组合 mov ax,[bx] mov ax,[si] mov ax,[di] mov ax,[dp] mov ax,[bx+si] mov ax,[bx+di] mov ax,[bp+si] mov a