汇编指令

VPP tips

别来无恙 提交于 2019-11-27 15:32:06
VPP tips 1. 性能从何而来。 原文链接: http://www.360doc.com/content/18/0428/20/53742993_749517107.shtml https://steeven.iteye.com/blog/2347150 DPDK代码级别性能优化总结 https://www.jianshu.com/p/346bf99b2fb1 https://www.jianshu.com/p/ed914b24f6da https://blog.csdn.net/Dgh19940/article/details/79603843 架构角度: DPDK 的巨页 、 NUMA 、 D-cache 优化, VPP 的 I-cache 优化 ; 算法角度: Bihash ,查表 lockless ; 代码角度: Vector 、 宏构造函数 、 结构体 cacheline 对齐 、 线程绑核 、指令预取、指令优化; 2. 路由查找 https://blog.csdn.net/dog250/article/details/6596046 Internet 路由之路由表查找算法概述 - 哈希 /LC-Trie 树 /256-way-mtrie 树 3. __constructor__ 修饰符 通过一个简单的例子介绍一下 gcc 的 __attribute__ (

C/C++中书写汇编指令

∥☆過路亽.° 提交于 2019-11-27 15:04:20
汇编语言的指令格式目前有两种不同的标准:Windows下的汇编语言基本上都遵循Intel风格的语法,比如:MASM、NASM,Unix/Linux下的汇编语言基本上都遵循AT&T风格的语法。 下面主要介绍Unix/Linux下的汇编,具体格式如下: [名称[:]] 指令码 源操作数SRC,目的操作数DST ;注释 开发一个OS,尽管绝大部分代码只需要用C/C++等高级语言,但是和硬件相关部分的代码需要使用汇编语言;由于启动部分的代码有大小限制,使用精练的汇编可以缩小目标代码的Size;另外,对于某些需要被经常调用的代码,使用汇编可以提高性能。 如果我们选择的OS开发工具是GCC以及GAS的话,就必须了解AT&T汇编语言语法,因为GCC/GAS只支持这种汇编语法。下面介绍GCC的内嵌汇编语法。 GCC 支持在C/C++代码中嵌入汇编代码,这些汇编代码被称作GCC Inline ASM——GCC内联汇编。这是一个非常有用的功能,有利于我们将一些C/C++语法无法表达的指令直接潜入C/C++代码中,另外也允许我们直接写 C/C++代码中使用汇编编写简洁高效的代码。 参考文章 : (1)如何在C或C++代码中嵌入ARM汇编代码 https://blog.csdn.net/Roland_Sun/article/details/42921131 (2)汇编与C/C++内联嵌入汇编 https:

cs:app--bomblab phase_1&&phase_2&&phase_3

喜你入骨 提交于 2019-11-27 12:43:13
大名鼎鼎bomblab实验 必要时需要自己画出函数栈帧! 必要时需要自己画出函数栈帧! 必要时需要自己画出函数栈帧! 由于不会作图,这里就不画了。 phase_1 通过反编译bomb文件得到phase_1的汇编代码 观察phase_1的汇编代码 观察将0x402400传入%esi, %esi是函数调用时的参数存放的寄存器,因为函数调用所用的寄存器都是依次有顺序的。%rdi, %rsi, %rdx, %rcx , %r8, %r9,发现直接%esi,可以推测%edi存放输入的字符串的地址。c语言中的字符串实际是字符指针。 进入函数strings_not_equal,由名字可以看出来是比较两个字符串是否相等的。%eax寄存器存放函数返回值。 test指令测试%eax是否为0,如果为0就证明该两个字符串相等。 关键是 0x402400 存放的字符串是什么。利用gdb可以查看存放在该地址的字符串 输入该字符串解决phase_1。 phase_2 汇编代码 我们先来看 第一部分 两条push指令将后面要用的的寄存器存放在栈上,然后栈底指针%rsp减0x28。 将%rsp的值给%rsi,作为参数存放的地址调用 read_six_numbers 函数。 第二部分 read_six_numbers的汇编代码 从0x401460——0x40147c,这些指令都是在为调用 __isoc99

双重检查锁单例模式为什么要用volatile关键字?

梦想的初衷 提交于 2019-11-27 10:41:44
前言 从Java内存模型出发,结合并发编程中的原子性、可见性、有序性三个角度分析volatile所起的作用,并从汇编角度大致说了volatile的原理,说明了该关键字的应用场景;在这补充一点,分析下volatile是怎么在单例模式中避免双检锁出现的问题的。 并发编程的3个条件 1、原子性:要实现原子性方式较多,可用synchronized、lock加锁,AtomicInteger等,但volatile关键字是无法保证原子性的; 2、可见性:要实现可见性,也可用synchronized、lock,volatile关键字可用来保证可见性; 3、有序性:要避免指令重排序,synchronized、lock作用的代码块自然是有序执行的,volatile关键字有效的禁止了指令重排序,实现了程序执行的有序性; 双重检查锁定模式 双重检查锁定(Double check locked)模式经常会出现在一些框架源码中,目的是为了延迟初始化变量。这个模式还可以用来创建单例。下面来看一个 Spring 中双重检查锁定的例子。 这个例子中需要将配置文件加载到 handlerMappings中,由于读取资源比较耗时,所以将动作放到真正需要 handlerMappings的时候。我们可以看到 handlerMappings前面使用了volatile。有没有想过为什么一定需要 volatile

双重检查锁单例模式为什么要用volatile关键字?

早过忘川 提交于 2019-11-27 10:39:15
前言 从Java内存模型出发,结合并发编程中的原子性、可见性、有序性三个角度分析volatile所起的作用,并从汇编角度大致说了volatile的原理,说明了该关键字的应用场景;在这补充一点,分析下volatile是怎么在单例模式中避免双检锁出现的问题的。 并发编程的3个条件 1、原子性:要实现原子性方式较多,可用synchronized、lock加锁,AtomicInteger等,但volatile关键字是无法保证原子性的; 2、可见性:要实现可见性,也可用synchronized、lock,volatile关键字可用来保证可见性; 3、有序性:要避免指令重排序,synchronized、lock作用的代码块自然是有序执行的,volatile关键字有效的禁止了指令重排序,实现了程序执行的有序性; 双重检查锁定模式 双重检查锁定(Double check locked)模式经常会出现在一些框架源码中,目的是为了延迟初始化变量。这个模式还可以用来创建单例。下面来看一个 Spring 中双重检查锁定的例子。 这个例子中需要将配置文件加载到 handlerMappings中,由于读取资源比较耗时,所以将动作放到真正需要 handlerMappings的时候。我们可以看到 handlerMappings前面使用了volatile。有没有想过为什么一定需要 volatile

重学计算机组成原理(五)- \"旋转跳跃\"的指令实现

不问归期 提交于 2019-11-27 06:21:06
CPU执行的也不只是一条指令,一般一个程序包含很多条指令 因为有if…else、for这样的条件和循环存在,这些指令也不会一路平直执行下去。 一个计算机程序是怎么被分解成一条条指令来执行的呢 1 CPU如何执行指令 CPU里差不多几百亿个晶体管 实际上,一条条计算机指令执行起来非常复杂 好在CPU在软件层面已经为我们做好了封装 对于程序员来说,我们只要知道,写好的代码变成了指令之后,是一条一条 顺序执行 不管几百亿的晶体管的背后是怎么通过电路运转起来的 逻辑上,我们可以认为,CPU其实就是由一堆寄存器组成的 而寄存器就是CPU内部,由多个触发器(Flip-Flop)或者锁存器(Latches)组成的简单电路。 触发器和锁存器,其实就是两种不同原理的数字电路组成的逻辑门 如果想要深入学习的话,可以学习数字电路的相关课程 N个触发器或者锁存器,就可以组成一个N位(Bit)的寄存器,能够保存N位的数据 比方说,我们用的64位Intel服务器,寄存器就是64位的 CPU里有很多种不同功能的 1.1 寄存器 寄存器(Register),是中央处理器内的其中组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。在中央处理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序计数器。在中央处理器的算术及逻辑部件中,包含的寄存器有累加器。 在计算机体系结构里

关于dword ptr 指令

筅森魡賤 提交于 2019-11-27 00:54:10
dword 双字 就是四个字节 ptr pointer缩写 即指针 []里的数据是一个地址值,这个地址指向一个双字型数据 比如mov eax, dword ptr [12345678] 把 内存地址 12345678中的双字型(32位)数据赋给eax 8086CPU的指令, 可以处理两种尺寸的数据 , byte和word 。 所以在机器指令中要指明,指令进行的是字操作还是字节操作 。对于这个问题,汇编语言中用一下方法处理。 (1)通过寄存器名指明要处理的数据的尺寸。 例如: 下面的指令中,寄存器指明了指令进行的是字操作: mov ax,1 mov bx,ds:[0] mov ds,ax mov ds:[0],ax inc ax add ax,1000 下面的指令中,寄存器指明了指令进行的是字节操作: mov al,1 mov al,bl mov al,ds:[0] mov ds:[0],al inc al add al,100 (2)在没有寄存器名存在的情况下, 用操作符 X ptr 指明内存单元的长度,X在汇编指令中可以为word或byte 。 例如: 下面的指令中,用word ptr 指明了指令访问的内存单元是一个字单元: mov word ptr ds:[0],1 inc word ptr [bx] inc word ptr ds:[0] add word ptr [bx]

网络变成操作系统详解

大城市里の小女人 提交于 2019-11-27 00:06:02
一 为什么要有操作系统 ( 两本书:现代操作系统、操作系统原理,学好python以后再去研究吧~~)   现代的计算机系统主要是由一个或者多个处理器,主存,硬盘,键盘,鼠标,显示器,打印机,网络接口及其他输入输出设备组成。   一般而言,现代计算机系统是一个复杂的系统。   其一:如果每位应用程序员都必须掌握该系统所有的细节,那就不可能再编写代码了(严重影响了程序员的开发效率:全部掌握这些细节可能需要一万年....)   其二:并且管理这些部件并加以优化使用,是一件极富挑战性的工作,于是,计算安装了一层软件(系统软件),称为操作系统。它的任务就是为用户程序提供一个更好、更简单、更清晰的计算机模型,并管理刚才提到的所有设备。 总结:    程序员无法把所有的硬件操作细节都了解到,管理这些硬件并且加以优化使用是非常繁琐的工作,这个繁琐的工作就是操作系统来干的,有了他,程序员就从这些繁琐的工作中解脱了出来,只需要考虑自己的应用软件的编写就可以了,应用软件直接使用操作系统提供的功能来间接使用硬件。 二 什么是操作系统    精简的说的话,操作系统就是一个协调、管理和控制计算机硬件资源和软件资源的控制程序。操作系统所处的位置如图1 #操作系统位于计算机硬件与应用软件之间,本质也是一个软件。操作系统由操作系统的内核(运行于内核态,管理硬件资源)以及系统调用(运行于用户态

VS2013中反汇编常用指令理解

*爱你&永不变心* 提交于 2019-11-26 23:17:56
  最近复习C语言,对反汇编感兴趣,就用下图举例解释一下我的理解,如有错还请大佬指教。   首先,认识两个常用指令 :    lea ---> 取地址赋值 mov ---> (同类型)赋值 其次理解 dword ptr [] :    dword(double word)即双字,也就是四字节    ptr(point)即指针    []放的是一个地址值,这个地址对应一个四字节数据 举个栗子, dword ptr [p1] 表示 : p1(地址值)对应的四字节数据(内容) 解释完了,现在把各部分汇编指令拿出来验证一下    来源: https://www.cnblogs.com/Duikerdd/p/11334962.html

堆栈,堆栈,堆和栈的区别【转载】

谁说我不能喝 提交于 2019-11-26 18:35:42
原文: http://www.cppblog.com/oosky/archive/2006/01/21/2958.html 非本人作也!因非常经典,所以收归旗下,与众人阅之!原作者不祥! 堆和栈的区别 一、预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。 3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放 5、程序代码区—存放函数体的二进制代码。 二、例子程序 这是一个前辈写的,非常详细 //main.cpp int a = 0; 全局初始化区 char *p1; 全局未初始化区 main() { int b; 栈 char s[] = "abc"; 栈 char *p2; 栈 char *p3 = "123456"; 123456\0在常量区,p3在栈上。