汇编指令

实战分析一个运行起来会卡死的Go程序

时光怂恿深爱的人放手 提交于 2020-02-21 08:20:27
序言 最近一位非常热心的网友建议结合demo来分析一下goroutine的调度器,而且还提供了一个demo代码,于是便有了本文,在此对这位网友表示衷心的感谢! 这位网友提供的demo程序可能有的gopher以前见过,已经知道了具体原因,但本文假定我们是第一次遇到这种问题,然后从零开始,通过一步一步的分析和定位,最终找到问题的根源及解决方案。 虽然本文不需要太多的背景知识,但最好使用过gdb或delve调试工具,了解汇编语言及函数调用栈当然就更好了。 本文我们需要重点了解下面这3个内容。 调试工具无法准确显示函数调用栈时如何找到函数调用链; 发生GC时,如何STOP THE WORLD; 什么时候抢占调度不会起作用以及如何规避。 本文的实验环境为AMD64 Linux + go1.12 Demo程序及运行现象 package main import( "fmt" "runtime" "time" ) func deadloop() { for { } } func worker() { for { fmt.Println("worker is running") time.Sleep(time.Second * 1) } } func main() { fmt.Printf("There are %d cores.\n", runtime.NumCPU()) goworker()

volitale 关键字

余生长醉 提交于 2020-02-21 04:16:41
一、前言 volitale 知识点主要涉及JAVA内存模型的知识点,volitale提供了内存可见性和禁止指令重排的功能。 参考文章: https://blog.csdn.net/eff666/article/details/67640648 二、知识点 1.内存可见性 对变量进行访问和赋值时,观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令。lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能: (1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成; (2)它会强制将对缓存的修改操作立即写入主内存; (3)如果是写操作,它会导致其他CPU中对应的缓存行无效。 处理器为了提高处理速度,不直接和内存进行通讯,而是将系统内存的数据独到内部缓存后再进行操作,但操作完后不知什么时候会写到内存。 如果对声明了volatile变量进行写操作时,JVM会向处理器发送一条Lock前缀的指令,将这个变量所在缓存行的数据写会到系统内存。这一步确保了如果有其他线程对声明了volatile变量进行修改,则立即更新主内存中数据。 但这时候其他处理器的缓存还是旧的

深入程序编译链接和装载过程

僤鯓⒐⒋嵵緔 提交于 2020-02-20 02:29:27
文章目录 预编译 编译 汇编 链接 基础先知 指令和数据 分析二进制可重定位目标文件 main.o 的组成 强符号和弱符号 符号表 链接过程分析 运行 提问:一个源文件是如何变成可执行文件的? 在linux中,使用GCC来编译程序,我们逐步来分析: 预编译 gcc -E hello.c hello.i 编译 gcc -S hello.i -o hello.s 汇编 gcc -c hello.s -o hello.o 链接 gcc hello.o -o hello 运行 ./hello 预编译 预编译阶段主要处理以"#"开头的预编译指令。 删除宏定义并作文本替换 递归展开头文件“#include” 处理#if、#ifdef、#elif、#else、#endif等 删除注释“//”和 “/* */” 添加行号和文件标识,以便编译器产生编译调试时的行号信息,以及产生错误或警号时能够显示行号 保留所有的#pragma指令 编译 词法分析 语法分析 语义分析 代码优化 生成汇编指令 汇编 将汇编指令转换成机器指令 链接 基础先知 指令和数据 局部变量属于指令,静态变量和全局变量属于数据。 int gdata1 = 10; //数据 int gdata2 = 0; //数据 强符号 int gdata3;//数据 static int gdata4 = 11; //数据 static int

第五周学习总结

橙三吉。 提交于 2020-02-19 23:24:29
信息安全系统设计基础第六周学习总结 【学习时间: 6 小时】 一、学习过程 1.一个处理器支持的指令和指令的字节级编码称为它的指令集体系结构。 2.程序员可见的状态: Y86程序中的每条指令都会读取或者修改处理器状态中的某些部分。这称为程序员可见状态。 3.存储器:从概念上来说是一个很大的字节数组,保存着程序和数据。 4.程序状态的最后一个部分是状态码Stat,它表明程序执行的总体状态;它会指示是正常运行还是出现了某种异常。 5.Y86指令不允许从一个存储器地址到另一个存储器地址,也不允许从立即数到存储器。 6.halt指令停止指令的执行。并将状态码设置为HLT。 7.Y86利用绝对地址进行寻址,而且使用小端法编码。 8.指令集的一个重要性质就是字节编码必须有唯一的解释。 9.Stat包括四种状态,除了AOK表示正常执行外,其他状态都会导致处理器停止。在更完整的设计中,处理器通常都会调用一个异常处理程序。 10.Y86与IA32代码主要的区别就是,前者需要多条指令去执行一条IA32指令完成的功能。 11.以“.”开头的是汇编器命令,它们告诉汇编器调整地址,以便在那产生代码或者是插入一些数据。 12.指令模拟器YIS 目的是模拟Y86机器代码程序的执行,而不用试图去模拟任何具体处理器实现的行为。 13.将很多的逻辑门组合成一个网,就能构建计算块,称为组合电路。限制如下:

信息安全系统设计基础第五周学习总结

ε祈祈猫儿з 提交于 2020-02-19 23:07:54
第四章 处理器体系结构 4.1 Y86指令集体系结构 指令集体系结构,包括定义各种状态元素、指令集和他们的编码、一组编程规范和异常事件处理。 程序员可见的状态:Y86程序中的每条指令都会读取或修改处理器状态的某些部分。 8个程序寄存器:%eax、%ebx、%ecx、%edx、%esi、%edi、%esp、%ebp。存储一个字。 存储器:可以理解为很大的字节数组,保存着程序和数据。Y86用虚拟地址来引用存储器位置。 物理地址:硬件和操作系统软件联合将虚拟地址翻译成实际,指明数据实际保存在存储器的那个位置。 状态码Stat,表明程序执行的总体状态。 Y86指令:基本上是IA32指令集的一个子集。 指令编码 每条指令的第一个字节表明指令的类型。高四位是代码部分,第四位是功能部分。 !指令集的重要性质——字节编码必须有唯一的解释。 Y86异常 Y86程序 没有伸缩寻址模式; !以“.”开头的词是汇编器命令 YIS(指令集模拟器)目的是Y86机器程序代码的执行 一些Y86指令的详情 两个特别的指令组合需要注意! 4.2 逻辑设计和硬件控制语言HCL 逻辑门 AND &&. OR ||. NOT 组合电路——将很多逻辑门组合成一个网,构建计算块。 !两个限制: (1) 两个或多个逻辑门的输出不能连接在一起,否则它们可能会使线上的信号矛盾,可能会导致一个不合法的电压或电路故障; (2)

汇编中的函数

孤者浪人 提交于 2020-02-17 15:13:38
文章目录 什么是函数 如何调用函数 什么是参数和返回值 什么是函数 函数就是一系列 指令的集合 ,为了完成某个会重复使用的特殊功能。 例如:向寄存器中存值。 如何调用函数 用JMP指令来执行函数 用CALL指令来执行函数 大多数情况下,我们都会使用call这个指令来调用函数,因为即使调用完了,程序也会retn回去,接着执行没有执行的指令,虽然jmp指令也可以往回跳,但是用起来不如call指令方便。 什么是参数和返回值 我们直接编写一个参数来分析一下 实现功能:得到任意两个整数的和 在这里,我们通常使用EAX这个寄存器来存储 返回值 ,使用寄存器来传递 参数 ,但是这不是一定的。这里涉及到跳转指令以及修改EIP值的指令,不是很了解的可以 点击这里 ,里面有详细介绍,汇编这东西我感觉比较抽象,只能多练,把模糊的地方多运行几次观察下返回情况,造它就完事儿了。 来源: CSDN 作者: 1匹黑马 链接: https://blog.csdn.net/qq_43573676/article/details/104355838

汇编指令英文全称

一世执手 提交于 2020-02-17 09:28:41
1.通用数据传送指令. MOV----> move MOVSX---->extended move with sign data MOVZX---->extended move with zero data PUSH---->push POP---->pop PUSHA---->push all POPA---->pop all PUSHAD---->push all data POPAD---->pop all data BSWAP---->byte swap XCHG---->exchange CMPXCHG---->compare and change XADD---->exchange and add XLAT---->translate 2.输入输出端口传送指令. IN---->input OUT---->output 3.目的地址传送指令. LEA---->load effective address LDS---->load DS LES---->load ES LFS---->load FS LGS---->load GS LSS---->load SS 4.标志传送指令. LAHF---->load AH from flag SAHF---->save AH to flag PUSHF---->push flag POPF---->pop flag PUSHD--

汇编语言(四)--第一个程序

大兔子大兔子 提交于 2020-02-17 09:16:56
第四章 第一个程序 4.1 一个源程序从写出到执行的过程 简要过程: 编写 ⟶ \longrightarrow ⟶ 编译 ⟶ \longrightarrow ⟶ 连接 ⟶ \longrightarrow ⟶ 执行 编写汇编源程序 使用文本编辑器,用汇编语言编写汇编源程序 对源程序进行编译连接 使用汇编语言编译程序对源程序文件中的源程序进行编译,产生 目标文件 ;再用连接程序对目标文件进行连接,生成可在操作系统中直接运行的 可执行文件 。 可执行文件 可执行文件中包含两部分内容: 程序(从原程序中的汇编指令翻译过来的机器码)和数据(源程序中定义的数据) 相关的描述信息(比如:程序有多大、要占多少内存空间等) 执行可执行文件中的程序 在操作系统中,执行可执行文件中的程序。 操作系统依照可执行文件中的描述信息,将可执行文件中的机器码和数据加载入内存,并进行相关的初始化(比如:设置CS:IP指向第一条要执行的指令),然后由CPU执行程序。 4.2 源程序 汇编指令 有对应的机器码的指令,可以被编译为机器指令,最终为CPU所执行 伪指令 没有对应的机器码的指令,最终不被CPU所执行。 谁来执行伪指令呢? 伪指令是由 编译器 来执行的指令,编译器根据伪指令来进行相关的编译工作 4.2.1 定义一个段 segment和ends是一对成对使用的伪指令,这是在写可被编译器编译的汇编程序时

第一篇:初识Python

可紊 提交于 2020-02-17 07:32:14
一 本节目标 二 了解编程语言 2.1 为什么要编程? 2.2 什么是编程语言? 2.3 编程语言分哪些种类? 三 python简介 3.1 Python的前世今身 3.2 Python可以应用于众多领域 3.3 python是一种怎样的语言 3.4 为何选择Python 3.5 Python解释器的种类 3.6 python解释器的发展史 四 python环境 五 python入门 5.1 第一句python代码 5.2 文件头 5.3 注释 5.4 执行脚本传入参数 5.5 了解pyc文件 六 变量 6.1 为何要有变量 6.2 变量的声明与引用 6.3 标识符命令规范: 6.4 变量的赋值 七 输入输出 八 简单的运算符 九 流程控制 9.1 条件语句 9.2 循环语句 十 本节练习 一 本节目标 了解编程语言 了解python及与其他语言的优劣对比 安装python解释器及环境变量配置、运行python交互式环境 打印hello world程序 初识变量、用户输入,流程控制,while循环 二 了解编程语言 2.1 为什么要编程? 解放人力 :让机器(比如计算机)按照人们事先为其编写好的程序自发地去工作 2.2 什么是编程语言? 人----------->汉语--------------->中国人 八格牙路----------->日本人 汪汪汪------------->狗

汇编跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等

梦想与她 提交于 2020-02-17 02:05:17
跳转指令分三类: 一、无条件跳转: JMP; 二、根据 CX、ECX 寄存器的值跳转: JCXZ(CX 为 0 则跳转)、JECXZ(ECX 为 0 则跳转); 三、根据 EFLAGS 寄存器的标志位跳转, 这个太多了. 根据标志位跳转的指令: JE ;等于则跳转 JNE ;不等于则跳转 JZ ;为 0 则跳转 JNZ ;不为 0 则跳转 JS ;为负则跳转 JNS ;不为负则跳转 JC ;进位则跳转 JNC ;不进位则跳转 JO ;溢出则跳转 JNO ;不溢出则跳转 JA ;无符号大于则跳转 JNA ;无符号不大于则跳转 JAE ;无符号大于等于则跳转 JNAE ;无符号不大于等于则跳转 JG ;有符号大于则跳转 JNG ;有符号不大于则跳转 JGE ;有符号大于等于则跳转 JNGE ;有符号不大于等于则跳转 JB ;无符号小于则跳转 JNB ;无符号不小于则跳转 JBE ;无符号小于等于则跳转 JNBE ;无符号不小于等于则跳转 JL ;有符号小于则跳转 JNL ;有符号不小于则跳转 JLE ;有符号小于等于则跳转 JNLE ;有符号不小于等于则跳转 JP ;奇偶位置位则跳转 JNP ;奇偶位清除则跳转 JPE ;奇偶位相等则跳转 JPO ;奇偶位不等则跳转 来源: CSDN 作者: Hoto Kokoa 链接: https://blog.csdn.net/weixin