云班课学习内容

一、C语言中嵌入汇编代码

1、内嵌汇编语法

(1)C语言中嵌入汇编代码的写法:

asm(

汇编语句模板:

输出部分:

输入部分:

破坏描述部分);

说明:输出部分和输入部分对应着C语言中的函数调用时的参数(return也是一个输出部分)

例:

printf("val1:%d,val2:%d,val3:%d\n",val1,val2,val3);
asm volatile(
/*asm是GCC关键字asm的宏定义,表示内嵌汇编语句,与__sam__同,volatile是GCC关键字volatile的宏定义,告诉编译器不要对代码进行优化,与__volatile同*//
"movl $0,%%eax\n\t" /*clear %eax to 0,两个%中第一个用于转义*/
"addl %1,%%eax\n\t" /*%eax+=val1,是输入输出中的第二个数*/
"addl %2,%%eax\n\t" /*%eax+=val2,是输入输出中的第三个数*/
"movl %%eax,%0\n\t" /*val3=%eax*/
:"=m"(val3) /*output=m,只写,m表示写入内存
:"c"(val1),"d"(val2) /*input c:ecx d:edx*/
);
printf("val1:%d+val2:%d=val3:%d\n",val1,val2,val3); return 0;

(2)内嵌汇编常用限定符

限定符 描述
“a” 将输入变量放入eax
“b” 将输入变量放入ebx
“c” 将输入变量放入ecx
“d” 将输入变量放入edx
“s” 将输入变量放入esi
“D” 将输入变量放入edi
“q” 将输入变量放入eax,ebx,ecx,edx中的一个
“r” 将输入变量放入通用寄存器,也就是eax,ebx,ecx,edx,esi,edi中的一个
“A” 放入eax和edx,吧、把eax和edx合成一个64位的寄存器
“m” 内存变量
“o” 操作数为内存变量,但是其寻址方式是偏移量类型
“V” 操作数为内存变量,但寻址方式不是偏移量类型
“.” 操作数为内存变量,但寻址方式是自动增量
“p” 操作数是一个合法的内存地址(指针)
“g” 将输入变量放入eax,ebx,ecx,edx中的一个或者作为内存变量
“X” 操作数可以是任何类型
“I” 0-31之间的立即数(用于32位移位指令)
“J” 0-63之间的立即数(用于64位移位指令)
“N” 0-255之间的立即数(用于out指令)
“i” 立即数
“n” 立即数,有些系统不支持数字以外的立即数,这些系统应该使用n
“=” 操作数在指令中是只写的(输出操作数)
“+” 操作数在指令中是读写类型的(输入输出操作数)
“%” 该操作数可以和下一个操作数交换位置

二、三个法宝:存储程序计算机、函数调用堆栈、中断

1、计算机是如何工作的?(总结)--三个法宝

(1)存储程序计算机:所有计算机基础性的逻辑框架。

(2)函数调用堆栈:计算机中非常基础性的东西。最早的计算机没有高级语言,只有机器语言和汇编语言时没有函数的概念。而高级语言中有函数的概念,需要堆栈机制,是高级语言可以运行的基础。

堆栈是C语言程序运行时必须的一个记录调用路径和参数的空间。

--函数调用框架

--传递参数

--保存返回地址(保存返回值,如eax)

--提供局部变量空间

--等等

C语言编译器对堆栈的使用有一套规则,同一段C语言程序在不同的操作系统中产生的汇编代码可能会有一些差异。

了解堆栈存在的目的和编译器对堆栈使用的规则是理解操作系统一些关键性代码的基础。

(3)中断:计算机帮程序员做的一些工作。

中断

早期计算机没有中断时,需要执行完一个程序之后再执行另一个程序。

有了中断,就有了多道程序设计,即在系统中同时跑多道程序。

当中断发生时,CPU会把当前的eip,esp,ebp都压到一个内核堆栈中。CPU和内核代码共同实现了保存和回复现场。

2、利用mykernel实验模拟计算机硬件平台。

(1)搭建一个虚拟平台

(2)使用Linux源代码把CPU的配置配置好

(3)执行

cd LinuxKernel/Linux-3.9.4
qeum -kernel arch/x86/boot/bzImage /*加载内核*/

实验中遇到问题



①编译Linux内核出现include/linux/compiler-gcc.h:103:30: fatal error: linux/compiler-gcc5.h: No such file or directory

解决方案





解决方案:将用户转换为root即可

编译中:



完成:

qemu -kernel arch/x86/boot/bzImage



在mykernel目录中:



cd mykernel

输入ls命令会发现,该文件夹中含有mymain.c和myinterrupt.c两个文件。

/*mymain.c中开始启动操作系统,入口*/
void __init_my_start_kernel(void)
{
int i = 0;
while(1)
{
i++;
if(i%100000 == 0)
printk(KERN_NOTICE "my_start_kernel here %d \n",i);/*每循环十万次,打印一条消息*/
}

void my_timer_handler(void)/*myinterrupt.c中,时钟中断处理入口*/
{
printk(KERN_NOTICE "\N>>>>>>>>>>>>>>>>>>>>>my_timer_handler here <<<<<<<<<<<\n\n");
}

当按照课本敲完代码只有,出现了很多错误,都是因为敲代码的时候不认真,多了字母、少了字母或者是代码敲错。其中值得一提的一个错误是在mymain.c文件中的初始化函数,init前面是两个下划线,而不是一个。

之后运行成功:

三、深入理解函数调用堆栈

1、(1)esp:堆栈指针

(2)ebp:基址指针

(3)堆栈操作:①push栈顶地址减少4个字节(32位)

②pop栈顶地址增加4个字节(32位)

(4)ebp在C语言中用作记录当前函数调用基址

(5)其他关键寄存器

cs:eip总是指向下一条的指令地址

顺序执行:总是指向地址连续的下一条指令

跳转/分支:执行这样的指令的时候,cs:eip的值会根据程序需要被修改

call:将当前cs:eip的值压入栈顶,cd:eip指向被调用函数的入口地址

ret:从栈顶弹出原来保存在这里的cs:eip的值,放入cs:eip中

(6)建立被调用者函数的堆栈框架

pushl %ebp
movl %esp,%ebp
/*被调用者函数体*/
/*拆除被调用者函数的堆栈框架*/
movl %ebp,%esp
popl %ebp
ret

2、堆栈调用

(1)首先使用gcc -g生成test.c的debug版本的可执行文件test,然后使用objdump -S 获得test的反汇编文件。

    objdump -S test > test.txt



注意为什么在反汇编代码中,是用变址寻址,而不是直接用x或者y?

是因为:参数已经放在了堆栈中,只需要根据地址寻找即可。

2019-2020-1 20199302《Linux内核原理与分析》第三周作业的更多相关文章

  1. 2019-2020-1 20199329《Linux内核原理与分析》第九周作业

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

  2. 2019-2020-1 20199329《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

  3. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  4. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

  5. 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  6. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

  8. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  9. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

  10. 2018-2019-1 20189221《Linux内核原理与分析》第二周作业

    读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...

随机推荐

  1. CodeForces-1152C-Neko does Maths

    C. Neko does Maths time limit per test:1 second memory limit per test:256 megabytes input:standard i ...

  2. Java找N个数中最小的K个数,PriorityQueue和Arrays.sort()两种实现方法

    最近看到了 java.util.PriorityQueue.刚看到还没什么感觉,今天突然发现他可以用来找N个数中最小的K个数. 假设有如下 10 个整数. 5 2 0 1 4 8 6 9 7 3 怎么 ...

  3. dubbo中使用动态代理

    dubbo的动态代理也是只能代理接口 源码入口在JavassistProxyFactory中 public class JavassistProxyFactory extends AbstractPr ...

  4. Feign 失败降级未生效和超时配置优先级问题

    一.问题: 生产环境服务A 通过feign调用 服务B,服务A报警信息如下: 详细分析发现问题 (1)服务A调用服务B失败,未触发声明的失败降级操作 (2)同时配置ribbon和feign超时时间,优 ...

  5. jmeter_图形监控

    图形监控插件下载: http://jmeter-plugins.org/downloads/all/   下载: JMeterPlugins-Standard-1.4.0 ServerAgent-2. ...

  6. FireWolf OS X PE

    FireWolf OS X PE FireWolf OS X PE 9 使用手册   https://pe.firewolf.app/manual/ https://pe.firewolf.app/m ...

  7. React Native 开发豆瓣评分(五)屏幕适配方案

    前言 React Native 是以实际像素 dp 为单位的,这导致在不同分辨率的屏幕会有不一样的显示情况. 在原生 Android 中,可以根据不同的分辨率添加不同的样式目录,以解决不同分辨率的问题 ...

  8. mysql 表关系 与 修改表结构

    目录 mysql 表关系 与 修改表结构 两张表关系 分析步骤 修改表结构 mysql 表关系 与 修改表结构 两张表关系 多对一 以员工和部门举例 多个员工对应一个部门 foreign key 永远 ...

  9. Fortify漏洞之Insecure Randomness(不安全随机数)

    继续对Fortify的漏洞进行总结,本篇主要针对  Insecure Randomness  漏洞进行总结,如下: 1.Insecure Randomness(不安全随机数) 1.1.产生原因: 成弱 ...

  10. iOS数组遍历

    对于一个数组 NSArray *array = @[@"111",@"222",@"333",@"444",@" ...