精华内容
下载资源
问答
  • 使用前在Windows平台需要安装python3.x 以及openpyxl模块,使用时将需要转换的模块寄存器按照examp.xlsx格式填好excel,excel文件名设置为寄存器名字,将excel和脚本文件放在一个目录下,具体使用时在cmd界面进入到...
  • ADS1118的寄存器非常简单,只有2个16bit的寄存器。其中一个为只读寄存器,保存ADC转换后的值;另一个为配置寄存器,配置采集通道、正负量程、采集模式、采集速率、采集源(电压或温度)等。 ADS1118的转换寄存器 ADS...
  • 前段时间群里有同学提说希望能在App的崩溃日志中得到崩溃现场当前方法中各个变量和其当前值(而不是只有寄存器),于是去调研了一下.dSYM文件格式,发现理论上是可行的。 二、方案 1. .dSYM 文件基本概念 .dSYM...

    一、背景

    前段时间群里有同学提说希望能在App的崩溃日志中得到崩溃现场当前方法中各个变量名和其当前值(而不是只有寄存器),于是去调研了一下.dSYM文件格式,发现理论上是可行的。

    二、方案

    1. .dSYM 文件基本概念

    .dSYM文件是Xcode在编译iOS工程过程中产生的符号文件,一般用于崩溃日志解析——将崩溃栈中的指令地址转换为实际代码文件及其对应行号。

    以下命令可以显示.dSYM文件中各个段的大小:

    $ size -m  xxx.dSYM/Contents/Resources/DWARF/xxx  
    

    我们感兴趣的是__DWARF段中的__debug_info节。

    2. __debug_info 数据

    __debug_info节中存放了各个函数的起始、结束地址及函数中各局部变量的变量名、类型、内存地址(相对于fp或其他寄存器)信息。

    以一个简单的测试方法为例:

    - (void)myFunction:(int) arg {
        int local = arg + 5;
        int i;
    
        for (i = 0; i < local; ++i)
            printf("i = %d\n", i);
    }
    

    编译出.dSYM文件后,运行以下命令可以导出__debug_info信息:

    $ dwarfdump --debug-info ./testDwarf.app.dSYM/Contents/Resources/DWARF/testDwarf
    

    其中与-[ViewController myFunction:]方法相关的部分如下:

    0x0004005f:     TAG_subprogram [122] *
                     AT_low_pc( 0x0000000100006760 ) //方法代码起始地址
                     AT_high_pc( 0x00000074 )        //方法代码长度
                     AT_frame_base( reg29 )          //指明此方法的frame base是x29(也就是fp),后面会用到
                     AT_object_pointer( {0x00040078} )
                     AT_name( "-[ViewController myFunction:]" )    //当前测试方法名
                     AT_decl_file( "/Users/jz/bsl/Tests/testDwarf/testDwarf/ViewController.m" )    //文件路径
                     AT_decl_line( 22 )    //行号
                     AT_prototyped( true )
    
    0x00040078:         TAG_formal_parameter [123]  
                         AT_location( fbreg -8 )
                         AT_name( "self" )
                         AT_type( {0x000400bb} ( const ViewController* ) )
                         AT_artificial( true )
    
    0x00040084:         TAG_formal_parameter [123]  
                         AT_location( fbreg -16 )
                         AT_name( "_cmd" )
                         AT_type( {0x000400c5} ( SEL ) )
                         AT_artificial( true )
    
    0x00040090:         TAG_formal_parameter [124]  
                         AT_location( fbreg -20 )        //AT_location字段表明此变量(参数 arg)的内存地址在当前函数的 AT_frame_base 偏移 -20 处,myFunction函数的AT_frame_base 为 x29,则参数arg的实际存放地址为 $x29 - 20
                         AT_name( "arg" )                //参数 arg 变量名
                         AT_decl_file( "/Users/jz/bsl/Tests/testDwarf/testDwarf/ViewController.m" )
                         AT_decl_line( 22 )
                         AT_type( {0x000400d8} ( int ) ) //具体类型信息,见下个代码片断
    
    0x0004009e:         TAG_variable [125]  
                         AT_location( breg31 +24 )       //局部变量 local 的存放位置为 breg31 + 24 == x31 + 24,其中:x31也就是sp
                         AT_name( "local" )              //局部变量local
                         AT_decl_file( "/Users/jz/bsl/Tests/testDwarf/testDwarf/ViewController.m" )
                         AT_decl_line( 23 )
                         AT_type( {0x000400d8} ( int ) ) //具体类型信息,见下个代码片断
    
    0x000400ac:         TAG_variable [125]  
                         AT_location( breg31 +20 )
                         AT_name( "i" )
                         AT_decl_file( "/Users/jz/bsl/Tests/testDwarf/testDwarf/ViewController.m" )
                         AT_decl_line( 24 )
                         AT_type( {0x000400d8} ( int ) )
    
    
    //arg和local的具体类型信息都指向 0x000400d8
    0x000400d8:     TAG_base_type [5]  
                     AT_name( "int" )
                     AT_encoding( DW_ATE_signed )
                     AT_byte_size( 0x04 )
    

    其中重点关注以下字段(详见上面代码片断中的注释):

    • AT_low_pc:此方法代码开始地址
    • AT_high_pc:此方法代码长度
    • AT_frame_base:方法的frame baseAT_location中如果使用的fbreg即取此frame base的值
    • AT_name:方法、参数、变量等的名称
    • AT_location:参数/变量的内存地址,上例中:
      • 参数arg为:fbreg - 20
        • 表明arg的存放地址在当前函数的AT_frame_base偏移-20处,myFunction函数的AT_frame_basex29,则参数arg的实际存放地址为$x29 - 20
      • 局部变量local为:breg31 + 24
        • 表明local的存放地址为breg31 + 24 == $x31 + 24,其中:x31也就是sp寄存器

    3. 数据验证

    下面验证一下实际的汇编指令是否与上面的__debug_info中的字段数据相吻合。

    • 执行以下命令可以将二进制反汇编为汇编语言:

      $ objdump -d ./testDwarf.app/testDwarf
      复制代码
      
      -[ViewController myFunction:]:
      100006760:  ff 03 01 d1     sub sp, sp, #64
      100006764:  fd 7b 03 a9     stp x29, x30, [sp, #48]
      100006768:  fd c3 00 91     add x29, sp, #48
      10000676c:  a0 83 1f f8     stur    x0, [x29, #-8]
      100006770:  a1 03 1f f8     stur    x1, [x29, #-16]
      100006774:  a2 c3 1e b8     stur    w2, [x29, #-20]
      100006778:  a2 c3 5e b8     ldur    w2, [x29, #-20]
      10000677c:  42 14 00 11     add w2, w2, #5
      100006780:  e2 1b 00 b9     str w2, [sp, #24]  //注:此处是对变量local的赋值,可对应上图中变量 local 的 AT_location( breg31 +24 ) 字段
      100006784:  ff 17 00 b9     str wzr, [sp, #20]
      100006788:  e8 17 40 b9     ldr w8, [sp, #20]
      10000678c:  e9 1b 40 b9     ldr w9, [sp, #24]
      100006790:  1f 01 09 6b     cmp w8, w9
      100006794:  aa 01 00 54     b.ge    #52
      100006798:  e8 17 40 b9     ldr w8, [sp, #20]
      10000679c:  e0 03 08 aa     mov x0, x8
      1000067a0:  e9 03 00 91     mov x9, sp
      1000067a4:  20 01 00 f9     str x0, [x9]
      1000067a8:  00 00 00 b0     adrp    x0, #4096
      1000067ac:  00 cc 19 91     add x0, x0, #1651
      1000067b0:  fd 00 00 94     bl  #1012
      1000067b4:  e0 13 00 b9     str w0, [sp, #16]
      1000067b8:  e8 17 40 b9     ldr w8, [sp, #20]
      1000067bc:  08 05 00 11     add w8, w8, #1
      1000067c0:  e8 17 00 b9     str w8, [sp, #20]
      1000067c4:  f1 ff ff 17     b   #-60
      1000067c8:  fd 7b 43 a9     ldp x29, x30, [sp, #48]
      1000067cc:  ff 03 01 91     add sp, sp, #64
      1000067d0:  c0 03 5f d6     ret
      
    • 观察-[ViewController myFunction:]方法的起始、结束地址,与__debug_info中的AT_low_pcAT_high_pc数值相吻合

    • 观察地址100006780处对局部变量local的赋值,其寻址方式为[sp, 24],也与AT_location的内容相吻合

    三、结论

    综上可知,通过分析.dSYM文件中的__DWARF__debug_info节中的具体信息,能够在运行时(特别是崩溃时)得到方法内变量名对应的实际存放位置(内存地址),根据需要dump出来相应内存的内容最后放到崩溃日志中即可实现原始需求。

    注:因为涉及符号文件解析,可能有两个方案来实现:

    • App中带上符号文件,崩溃时实时解析
    • 将整个栈区内容dump下来,发到服务器上做具体解析 应该都只能用在内测版上。

    注:此文只做了基本方案调研,工程化上还有很多需要考虑的点,可能还得实现或改造一个DWARF解析器,不在本文讨论范围之内。

    参考资料

    推荐👇:

    作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:789143298 ,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!

    申请即送:

    • ——点击加入:iOS开发交流群

    • BAT大厂面试题、独家面试工具包,

    • 资料免费领取,包括 数据结构、底层进阶、图形视觉、音视频、架构设计、逆向安防、RxSwift、flutter,


      作者:zhangjiezhi_
      链接:https://juejin.im/post/6883160410736820231

    展开全文
  • CPU中的寄存器和地址概念

    万次阅读 2016-03-17 10:18:12
    一般的CPU都是由以下部分组成:运算器、控制器和寄存器。 这些器件之间自然也要相互交换信息,所以他们也是有导线相连的,也就是总线了。但是这个总线是内部总线,而CPU和内存、显卡之类做信息交换的是外部总线。 ...

    一般的CPU都是由以下部分组成:运算器、控制器和寄存器。

    这些器件之间自然也要相互交换信息,所以他们也是有导线相连的,也就是总线了。但是这个总线是内部总线,而CPU和内存、显卡之类做信息交换的是外部总线。

    他们的作用分别是:

    运算器:信息处理

    寄存器:信息储存

    控制器:控制器件

    好吧,从名字来看就很容易明白……

    通用寄存器(8086CPU):

    8086CPU寄存器都是16位的,可以存放两个字节,一个字节是八个二进制位哦。

    它的通用寄存器有:AX,BX,CX,DX,话说就是ABCD嘛。

    特殊的是这些寄存器都是可以拆成8位寄存器来使用,为了兼容。

    AX可以拆分为AHAL

    BX可以拆分为BXBL

    CX可以拆分为CHCL

    DX可以拆分为DHDL

    H代表high的意思,L代表low的意思,这样是不是很好理解。

    这个16位寄存器,说起来就是它里面可以存放0和1的小格子有16个。一个小格子就是一个二进制位。

    来张图应该会很清晰,没网……以后补充吧……

    说到这里,如果你看到这样的一个数字4E2C,不用慌张,它是一个16进制的数据。这种类型的数据,你只要死死记住,16禁止的一位,相当于二进制的四位,所以呢4E2C你要是换算成二进制,它是16个。

    书上的例子是这样的:

    4E20,这是一个16进制数,换算以后成二进制:0100111000100000,

    4就是0100,E就是1110,2就是0010,0就是0000.怎么换算还不知道,请打你的计算机老师……

    最后,有些时候我们不能一眼看出它是一个16进制数,或者说会有误解的时候,就会在十六进制数的后面加上一个H,这里的H不是high,而是Hex的意思。

    二进制数呢,就会在后面加上B,也就是byte的意思,而十进制数就不用加了,毕竟都是小学都会的。

    现在来使用寄存器吧!

    首先呢,在写汇编代码的时候,你不用区分大小写。

    比如:mov ax 22,这个是可以,他表示将22的数据送入AX寄存器

    不仅可以把数据送进寄存器,还可以把其它寄存器的数据送过来,如:mov ax bx 它表示把BX中的数据送入AX,当然,BX的数据还在的哦。

    如果你很高兴,mov AX 22 mov AX BX这种大写代码也是可以接受的……

    这里说到了mov ax bx的情况,有时候如果说ax寄存器没有数据,那么一切ok,但是如果ax里面有数据会怎么样?这个时候把bx的数据送进来,那ax的数据还在吗?

    答案是否定的,ax的数据将会被bx中传递过来的数据覆盖。

    其实很好理解,这个ax这个容器很小,当你把别的数据是送进来,它只能以这种方式存储数据。

    物理地址

    这里说的可不是你的MAC地址……

    在内存当中,不管你的内存有多大,CPU在访问的时候都是把它当成一维的,这样确保了每个内存单元都有唯一的地址。嗯,不排除以后科技更牛逼……

    这些内存单元的地址,就是它们的物理地址。

    CPU会首先在内部安排好地址,然后再发出去。那么CPU是怎么发出地址的?自然是靠地址总线。

    这里说的内存单元,绝不仅仅是内存条,还有显存之类的也属于内存单元。

    在讨论CPU问题,其实涉及到的是计算机的工作原理,和本质,我们不应当将概念人为地局限为一个或者一种特殊器件。

     

     

    展开全文
  • vim:命令模式下粘贴寄存器内容

    千次阅读 2012-12-18 10:16:11
    vim中,复制一些内容就是将内容放到寄存器里。 而在命令模式下粘贴寄存器的内容方法是 CTRL-R加寄存器的名字。 复制之后的内容一般在寄存器"中。 举例说明: 比如visual模式下复制了内容:aaabbb。 ...

    原文出處: http://www.kukaka.org/home/content/520

    vim中,复制一些内容就是将内容放到寄存器里。

    而在命令模式下粘贴寄存器的内容方法是

    CTRL-R加寄存器的名字。

    复制之后的内容一般在寄存器"中。

    举例说明:

    比如visual模式下复制了内容:aaabbb。

    然后希望替换这些内容,于是输入命令:

    %s/

    这个时候使用Ctrl-R在按",那么复制的内容就会出现在命令行中。

    展开全文
  • C51寄存器详解(Reg51.h)

    2013-09-12 18:19:00
    这个头文件将C程序中能用到的寄存器名寄存器中某位的名称与硬件地址值做了对应,在程序中直接写出这些名称,集成开发环境就能识别,并最终转换成机器代码,实现对单片机各硬件资源的准确操控。 REG51内部规定...

    Reg51.h

     

    这个头文件将C程序中能用到的寄存器名或寄存器中某位的名称与硬件地址值做了对应,在程序中直接写出这些名称,集成开发环境就能识别,并最终转换成机器代码,实现对单片机各硬件资源的准确操控。

     

    REG51内部规定的SFR寄存器的地址,1.SFR是Special Function Register(特殊功能寄存器)的缩写。

      SFR是80C51单片机中各功能部件对应的寄存器,用于存放相应功能部件的控制命令,状态或数据。它是80C51单片机中最具有特殊的部分,现在所有80C51系列功能的增加和扩展几乎都是通过增加特殊功能寄存器SFR来达到目的的。

      对于80C51系列中的80C51,共定义了21个特殊功能寄存器。在80C52中,除了80C51的21个特殊功能寄存器,还增加了5个,共计26个:

     
    * BYTE Register */
    sfr P0 = 0x80; //P0口
    sfr P1 = 0x90; //P1口
    sfr P2 = 0xA0; //P2口
    sfr P3 = 0xB0; //P3口
    sfr PSW = 0xD0; //程序状态字,具体位意义见位定义
    sfr ACC = 0xE0; //累加器,程序员最常用的
    sfr B = 0xF0; //寄存器,主要用于乘除
    sfr SP = 0x81; //堆栈指针,初始化为07;先加1后压栈,先出栈再减1,
    sfr DPL = 0x82;
    sfr DPH = 0x83; //数据指针,用途大
    sfr PCON = 0x87; //电源控制
    sfr TCON = 0x88; //Timer/Counter控制
    sfr TMOD = 0x89; //Timer/Counter方式控制
    sfr TL0 = 0x8A;
    sfr TL1 = 0x8B; //
    sfr TH0 = 0x8C; //存着当前的计数值
    sfr TH1 = 0x8D; //我就想不明白,当时设计的时候,为什么不把TH0,TL0放在连续的地址!
    sfr IE = 0xA8; //好东西,中断控制
    sfr IP = 0xB8; //中断优先级控制,没有设计过要求时间严格的系统,所以至今没有用过
    sfr SCON = 0x98; //哇,熟悉,串口控制寄存器
    sfr SBUF = 0x99; //哇,更熟悉,串口缓冲寄存器




    sbit CY = 0xD7; //进位或借位,有就是1,没有就是0
    sbit AC = 0xD6; //辅助进借位,(麻烦b)
    sbit F0 = 0xD5; //没有具体用途,可以由用户决定他的意义,所以它就没有意义
    sbit RS1 = 0xD4;
    sbit RS0 = 0xD3; //工作寄存器选择,这个在下面解释
    sbit OV = 0xD2; //over!溢出,有是1,没有是0
    sbit P = 0xD0; //奇偶校验,奇数个1是1


    sbit TF1 = 0x8F; //T1的中断请求标志
    sbit TR1 = 0x8E; //Timer 1 running,好记吧~
    sbit TF0 = 0x8D; //
    sbit TR0 = 0x8C; //把上面两个1换成0
    sbit IE1 = 0x8B; //interrupt external 1 外中断请求标志
    sbit IT1 = 0x8A; //interrupt triggle 1 外中断触发方式
    sbit IE0 = 0x89;
    sbit IT0 = 0x88; //同样,把上面的两个1换成0


    sbit EA = 0xAF; //Enable all哇,重要,全局中断控制,光着他,哈哈,什么都不用作了,就像放假一样
    sbit ES = 0xAC; //Enable Serial,开串口中断
    sbit ET1 = 0xAB; //Enable Timer/Counter 1
    sbit EX1 = 0xAA; //Enable External 1
    sbit ET0 = 0xA9; //Enable Timer/counter 0
    sbit EX0 = 0xA8; //Enable External 0


    sbit PS = 0xBC; //串行中断优先级
    sbit PT1 = 0xBB; //T1优先级
    sbit PX1 = 0xBA; //外部中断1优先级
    sbit PT0 = 0xB9; //
    sbit PX0 = 0xB8; //上面两个1换成0

    //控制寄存器!!!!
    sbit RD = 0xB7; //读
    sbit WR = 0xB6; //写
    sbit T1 = 0xB5; //T/C1
    sbit T0 = 0xB4; //T/C0
    sbit INT1 = 0xB3; //外中断1
    sbit INT0 = 0xB2; //外中断0
    sbit TXD = 0xB1; //串行发送
    sbit RXD = 0xB0; //串行接收


    sbit SM0 = 0x9F; //
    sbit SM1 = 0x9E; //串口工作方式
    sbit SM2 = 0x9D; //什么鬼特征位,要用查书,或者等我以后解释,啊哈
    sbit REN = 0x9C; //串行接收允许
    sbit TB8 = 0x9B; //收到的第九位
    sbit RB8 = 0x9A; //要发的第九位
    sbit TI = 0x99; //哇,熟悉吧,发送完成中断标志
    sbit RI = 0x98; //接收完成中断标志

    转载于:https://www.cnblogs.com/perfy/p/3317531.html

    展开全文
  • 在keil 中 C语言的函数有带...事实上,不管C语言的函数是否带参数,只要函数在调用过程中不用寄存器传递参数,生成的汇调用址(函数)都是原来的函数。 比如:#pragma noregparmsvoid fun(unsigned int a,unsigne...
  • 基数转换子程序

    2017-04-04 16:58:50
    寄存器EAX中的32位无符号二进制数转换为P进制数(P为 3-16 中任何一个整数) P进制的ASCII码按照高位在前,低位在后的顺序存放在SI指定的首址的字节存储区域; 子程序: radix ; 功能: 将EAX中的32位无符号二...
  • 子程序:ASCII_TO_BCD ;功能:将一个16位二制数转换成BCD码形式 ;入口参数:要转换的数存放到AX ;出口参数:转换完后放回到AX ;使用寄存器:AX, BX, CX, DX ;示例:若AX = 176FH,调用子程序后,AX = 5999 MOV ...
  • 变量和符号表

    千次阅读 2015-07-26 02:16:17
    变量是给编译器看的,编译器根据变量是局部还是全局分配内存地址或栈空间,所谓的变量在内存中不存在,操作时转换成地址数存放在寄存器中了。其实可以理解为是符号表起到了连接作用。 (二)符号表 ...
  • 【需求场景】 ...,现在工具了,工具和参数以及使用方式都变了,变成了echo "<devsel> <reg> <val>" > /sys/class/ti-spi/ads/write。但是,之前写的那些脚本散落在各个目...
  • 变量:用来标识一块内存区域,即变量就是一块内存...变量是给编译器看的,编译器根据变量是局部还是全局分配内存地址或栈空间,所谓的变量在内存中不存在,操作时转换成地址数存放在寄存器中了。 编译器会将...
  • 汇编常用指令

    万次阅读 多人点赞 2018-10-06 14:28:08
    通用寄存器及使用 IA-32系列有8个32位通用寄存器...中文 格式 解释 备注 location MOV 传送指令 MOV DEST,SRC DEST&amp;lt;=SRC P20 XCHG 交换指令 XCHG OPER1,OPER2 把操作数oper1的内容与操作数oper...
  • 1、变量是给编译器看的,编译器根据变量是局部还是全局分配内存地址或栈空间,所谓的变量在内存中不存在,操作时转换成地址数存放在寄存器中了。其实可以理解为是符号表起到了连接作用。 2、符号表(此段摘抄...
  • 在实时调整屏幕背景颜色及其它字符颜色时, 为了使程序具有良好的通用性, 使用了各种显示系统通用的调色板寄存器方法, 比如可事先设置背景使用0号调色板,汉字使用2 号调色板, 之后通过调整0号和2号调色板寄存器值, 可...
  • 英文Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。...
  • 一、预备知识 1.汇编语言基础 ... 寄存器名 说明 功能 eax: 累加器 加法乘法指令的缺省寄存器 ecx: 计数器 REP&LOOP指令的内定计数器 esp: 栈顶指针寄存器 SS:ESP当前堆栈的栈顶
  • example.xlsx

    2020-11-02 15:35:37
    脚本使用python实现excel到寄存器模型文件的转换功能。使用前电脑端需要安装python3.x 以及必要的模块,使用时将需要转换的模块寄存器按照examp.xlsx格式填好excel,excel文件名设置为寄存器名字即可,具体使用时在...
  • 为ShuChu的过程,用于将BX寄存器中的十六位二进制数转换为一个十进制数,并将其送显示器输出;试设计一个主过程, 调用已给出的两个子过程,实现从键盘获取两个十进制数, 相加后从显示器输出结果。
  • 计算机栈原理

    2018-11-20 10:51:21
     本篇文章着重写的是系统中栈的工作原理,以及函数调用过程中栈帧的产生与释放的过程,有可能名字过大,如果不合适我可以一个名字,希望大家能够指正,小丁虚心求教!如果有哪里写的不清楚的或者错误的地方请及时...
  • XML文件编写好后,通过主站程序下载到从站设备的EEPROM中,通过I2C总线与ET1100芯片内部的寄存器进行数据交换,实现配置信息的读取。从站设备描述文件的主要功能是描述EtherCAT从站的配置信息,主要包含以下两个部分...
  • 打开vs,写入代码,增加断点之后点击调试》开始调试,再点击调试》窗口,会出现...但是这里没有SF、ZF等标志位,只不过是了个名字,看下表:根据这个可以找到OF、SF等标志位。溢出标志OF(Over flow flag) OV(1) ...
  • 只有用作头文件时调试正确,而成就报错很多。我知道两个头文件中位定义的格式不一样,但把^改成_之后依旧报错。 ``` #include <reg52.h> //此文件中定义了单片机的一些特殊功能寄存器 #include ...

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 290
精华内容 116
关键字:

寄存器换名