精华内容
下载资源
问答
  • C语言寄存器的位操作

    千次阅读 2020-08-30 12:18:36
    C语言位操作 1、位操作符 (1)位与& 逻辑与&& 1&1=1 1&0=0 0&0=0 0&1=0 (2)位或 | 逻辑或 || 1 | 1=1 1 | 0=1 0 | 0=0 0 | 1=1 (3)位取反~ 逻辑取反 ! (4)位...

    C语言位操作

    1、位操作符

    (1)位与& 逻辑与&& 1&1=1 1&0=0 0&0=0 0&1=0

    (2)位或 | 逻辑或 || 1 | 1=1 1 | 0=1 0 | 0=0 0 | 1=1

    (3)位取反~ 逻辑取反 !

    (4)位异或 ^ 不同为1,相同为0 1^1=0 1^0=1 0^0=0 0^1=1

    总结:

    • 位操作是按照二进制数的每一位进行操作的,逻辑操作是对数的整体操作的
    • 位与,与1位与无变化,与0位与为0
    • 位或,与1位或为1,与0位或无变化
    • 位异或,与1位异或会取反,与0位异或无变化

    (5)移位操作

    • C语言的移位要取决于数据类型

    • 左移位 << 右移位 >>

      • 无符号数, 逻辑移位

        左移位时右侧补0

        右移位时左侧补0

      • 有符号数, 算数移位

        左移位时右侧补0(相当于逻辑移位)

        右移位时左侧补符号位,如果是正数就补0,负数就补1(第一位为符号位,0为正,1为负)

    2、位操作符在操作寄存器时的特殊作用

    (1)寄存器的操作要求

    • ARM是内存和IO统一编址的,CPU通过向内部外设的寄存器写入特定值来操作内部外设
      • 寄存器特点:按位进行规划和使用、读写是32位整体进行操作的
    • 寄存器的操作要求:操作寄存器时,要求改变某一特定位,而不影响其他位
    • 如何实现:读出—>改相应位—>写入

    (2)改相应位的操作

    ​ 基本思路:寄存器特定位改变而不影响其他位,构造合适的1和0组成的数和这个寄存器原来的值位与、位或、位取反

    • 特定位清零用 & (用0清零)

      • 与1位与无变化、与0位与变为0

      • 要清零的位为0,其他位为1,然后这个数与原数位与

      • 举例:原32位寄存器的值位0xAAAAAAAA,对bit2~bit8清零

        ​ 0xAAAAAAAA & 0xFFFFFE03

    • 特定位置1用 | (用1置1)

      • 与1位或为1,与0位或无变化

      • 要置1的位为1,其他位为0,然后这个数与原数位或

      • 举例:原32位寄存器的值位0xAAAAAAAA,对bit8~bit15置1

        ​ 0xAAAAAAAA | 0x0000FF00

    • 特定位取反用^ (用1取反)

      • 与1位异或为会取反,与0位异或无变化

      • 要取反的位为1,其他位为0,然后这个数与原数位异或

      • 举例:原32位寄存器的值位0xAAAAAAAA,对bit8~bit15取反

        ​ 0xAAAAAAAA ^ 0x0000FF00

    • 代码举例

      unsigned int a = 0xa12aaaa7;
      unsigned int b = 0xFFFF00FF;
      unsigned int c;
      c = a & b;
      // 16进制数的打印
      printf("a & b = %#X.\n", c);
      printf("a & b = 0x%x.\n", c);
      

    3、使用位运算构建特殊二进制数

    (1)使用位移获取特定位为1的二进制数

    • 获取bit3-bit7为1,同时bit23-bit25为1,其余都为0的数
      • (0x1F<<3) | (0x7<<23)

    (2)使用位移获取特定位为0的二进制数

    • 获取bit4-bit10为0,其余都为1的数
      • bit4-bit10为0也就是bit0-bit3为1同时bit11-bit31为1
        (0xF<<0) | (0x1FFFFF<<11)
      • ~(0x7F<<4)

    (3)总结

    • 1少0多,连续多个1左移n位
    • 0少1多,先构建其位反数,再按位取反
    • 连续1(0)不止一个,则通过分段分别构建,再彼此位与即可

    4、位运算的操作实战

    ​ 回顾:清零用&,置1用 | ,取反用^

    ​ ~和<< >>用来构建特定二进制数

    unsigned int a ; // 定义无符号数,如果是有符号数,那么位移就会出问题

    (1)给定一个整型数a,设置a的bit3,保证其他位不变

    • a |= (0x1<<3)

    (2)给定一个整型数a,设置a的bit3-bit7,保证其他位不变

    • a |= (0x1F<<3) a |= (0b11111<<3)

    (3)给定一个整型数a,清除a的bit15,保证其他位不变

    • a &= (~(0x1<<15)) a = (a | (0x7FFF<<0) | (a | (0xFFFF<<16) (不采用)

    (4)给定一个整型数a,清除a的bit15-bit23,保证其他位不变

    • a &= (~(0x1FF<<15))

    (5)给定一个整型数a,取出a的bit3-bit8

    • 先将a的bit3-bit8不变,其余位清零
      • a &= (0x3F<<3)
    • 再将a右移3位
      • a >>= 3

    (6)给寄存器的bit7-bit17赋值937,其余位不受影响

    • 先将bit7-bit17全部清零,其他位不变
      • a &= (~(0x7FF<<7))
    • 再将937写入bit7-bit17,其他位不变
      • a |= (937<<7)

    (7)将寄存器bit7-bit17中的值加17,其余位不受影响

    • 先读出bit7-bit17的值
      • temp = a & (0x7FF<<7)
      • temp >>= 7;
    • 给temp加17
      • temp += 17
    • 将bit7-bit17清零
      • a &= (~(0x7FF<<7))
    • 将temp算出的值写入到bit7-bit17
      • a |= (temp<<7)

    (8)给寄存器bit7-bit17赋值937,同时给bit21-bit25赋值17

    • 先将bit7-bit17和bit21-bit25清零,其他位不变
      • a &= (~ ( (0x7ff<<7) | (0x1f<<21) ) ) // 位或优先级高于~
    • 再将937赋值到bit7-bit17,17赋值到bit21-bit25
      • a |= ((937<<7) | (17<<21))

    printf(“a = %u.\n”, a); // %u 打印无符号数

    5、技术升级:使用宏定义来完成运算

    (1)直接用宏定义来置位、复位(最右边是第一位,bit0)

    // 置位
    #define SET_NTH_BIT(x, n)	(x | ( (1U) << (n-1) )  )
    // 复位
    #define CLEAR_NTH_BIT(x, n)	(x & ~ ( (1U) << (n-1) )  )
    // 1后边的U表示这个数字是无符号数(有符号数的右移是会出问题的)
    

    (2)将32位数x的第n位到第m位置位

    // 关键点:我们需要一个算式来得到(m-n+1)个1的十六进制数
    // 第1步,先得到32个1: ~0U	(~按位取反得到32个1,如果直接1U那么就只有bit0位1)
    // 第2步,将得到的数右移x位即可得到(m-n+1)个: (~0U) >> (32-(m-n+1)) 或 ~(~0U<<(m-n+1))
    #define SET_BIT_N_M(x, n, m)	(x | (((~0U) >> (32-(m-n+1))) << (n-1)))
    #define SET_BIT_N_M(x, n, m)	(x | ~(~0U<<(m-n+1))<<(n-1))
    

    (3)截取变量的部分连续位(相当于4中的(5))

    // 给定一个整型数a,取出a的bit3-bit8
    //   先将a的bit3-bit8不变,其余位清零	    a &= (0x3F<<3)
    //   再将a右移3位					   a >>= 3
    #define GETBITS(x, n, m)	(x & ~(~0U << (m-n+1)) << (n-1)) >> (n-1))
    // 思路:
    // 	先将x的bit(n-1)-bit(m-1)不变,其余位清零
    //		得到(m-n+1)个1的十六进制数    ~(~0U << (m-n+1))                (得到0x3F)
    //		将得到的16进制数左移(n-1)     ~(~0U << (m-n+1)) << (n-1)       (得到0x3F<<3)
    // 		x和左移后的数位与             x & ~(~0U << (m-n+1)) << (n-1)   (a &= (0x3F<<3))
    // 	再将x右移(n-1)位
    // 		位与后的数右移(n-1)		  (x & ~(~0U << (m-n+1)) << (n-1)) >> (n-1)
    // 最终结果
    #define GETBITS(x, n, m)	(x & ~(~0U << (m-n+1)) << (n-1)) >> (n-1))
    
    // 得到(m-n+1)个1的十六进制数的两种方式:
    // 		32位的1先左移(m-n+1)位,那么低(m-n+1)位位0,高(32-(m-n+1))位为1,再将其按位取反,
    // 						   就得到低(m-n+1)位为1,高(32-(m-n+1))位为0。
    				~(~0U << (m-n+1))
    // 		有(m-n+1)个1,那么就有32-(m-n+1)个0,将32位的1先右移32-(m-n+1),
    // 							那么高32-(m-n+1)位为0,低(m-n+1)位为1。
    				(~0U) >> (32-(m-n+1))
    
    展开全文
  • 汇编打印寄存器值

    千次阅读 2019-04-17 12:37:29
    有时在调试时,需要讲寄存器值打印出来,但是在汇编中,不能直接调用打印函数。只能利用汇编直接往串口输出。特记录如下: mov r9, r2 ldr r8, =0x02020040 //串口地址 mov r7, #'\n' str r7, [r8] // 0-3 ...

     

    mov  r2, 0x5000

    movt r2, 0x1100

    mov r1, #'A'

    1:

     str r1, [r2]

    b 1b

    有时在调试时,需要讲寄存器值打印出来,但是在汇编中,不能直接调用打印函数。只能利用汇编直接往串口输出。特记录如下:


            mov r9, r2
            ldr r8, =0x02020040   //串口地址
            mov r7, #'\n'
            str r7, [r8]
            // 0-3
            and r9, r9, #15
        // ascii 转换
        ADD   r9, r9, #48
            CMP   r9, #58              ; did that exceed ASCII '9'?
            ADDHS r9, r9, #7           ; add 'A' - ('0'+10) if needed
            str r9, [r8]
           
            // 4-7
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #4
            and r9, r9, #15
            str r9, [r8]

            // 8-11
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #8
            and r9, r9, #15
            str r9, [r8]

            // 12-16
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #12
            and r9, r9, #15
            str r9, [r8]

            // 17-20
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #16
            and r9, r9, #15
            str r9, [r8]

            // 21-24
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #20
            and r9, r9, #15
            str r9, [r8]

            // 25-28
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #24
            and r9, r9, #15
            str r9, [r8]
            
            //29-32bit
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #28
            and r9, r9, #15
            str r9, [r8]

            
            
            mov r7, #'\n'
            str r7, [r8]
            mov r7, #'\n'
            str r7, [r8]
            mov r7, #'\n'
            str r7, [r8]

            mov r9, r3
            ldr r8, =0x02020040
            mov r7, #'\n'
            str r7, [r8]
            // 0-3
            and r9, r9, #15
            str r9, [r8]
           
            // 4-7
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #4
            and r9, r9, #15
            str r9, [r8]

            // 8-11
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #8
            and r9, r9, #15
            str r9, [r8]

            // 12-16
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #12
            and r9, r9, #15
            str r9, [r8]

            // 17-20
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #16
            and r9, r9, #15
            str r9, [r8]

            // 21-24
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #20
            and r9, r9, #15
            str r9, [r8]

            // 25-28
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #24
            and r9, r9, #15
            str r9, [r8]
            
            //29-32bit
            mov r7, #'\n'
            str r7, [r8]
            mov r9, r2
            ror r9, #28
            and r9, r9, #15
            str r9, [r8]

     

    展开全文
  • 使用C语言来访问ARM寄存器的语法

    千次阅读 2019-12-25 09:58:04
    ARM寄存器的地址类似于内存地址(IO与内存统一编址的),所以这里的问题是用C语言读写寄存器,就是用C语言来读写内存地址。用C语言来访问内存,就要用到指针:例如某寄存器的地址为0xE0200240; define GPJ0CON 0xE...

    ARM寄存器的地址类似于内存地址(IO与内存统一编址的),所以这里的问题是用C语言读写寄存器,就是用C语言来读写内存地址。用C语言来访问内存,就要用到指针:例如某寄存器的地址为0xE0200240;

    define GPJ0CON 0xE0200240

    unsigned int *p = (unsigned int *)0xE0200240;

    *P = 0x11111111;

    上面这两句其实可以简化为1句:

    *((unsigned int *)0xE0200240) = 0x11111111;

    因为

    (unsigned int *)0xE0200240就等于p,我们就直接把(unsigned int *)0xE0200240当p 用,

    *((unsigned int *)0xE0200240) = 0x11111111;

    那么我们就可以把整个表达式*((unsigned int *)GPJ0CON)定义为一个宏

    #define rGPJ0CON *((volatile unsigned int *)GPJ0CON)               //用volatile 是让编译器不要优化

    那么rGPJ0CON就可以当做变量p来用了

     

    例:

    define GPJ0CON 0xE0200240

    define GPJ0DAT 0xE0200244

    unsigned int *p = (unsigned int *)GPJ0CON;

    *p = 0x11111111;

    unsigned *p1 = (unsigned int *)GPJ0DAT;

     

    展开全文
  • arm上获取寄存器

    千次阅读 2017-11-16 14:29:41
     本来说在arm上获取寄存器是因为需要调试一个很古怪的问题,而在自己的机器上测试的386结构的代码似乎还不如arm上对register的访问自由。大致的想了想似乎arm上得到寄存器很简单的样子。所以之前才说可能在...

    http://blog.chinaunix.net/uid-20228521-id-1971079.html



     本来说在arm上获取寄存器的值是因为需要调试一个很古怪的问题,而在自己的机器上测试的386结构的代码似乎还不如arm上对register的访问自由。大致的想了想似乎arm上得到寄存器的值很简单的样子。所以之前才说可能在arm上会比较简单。结果今天上午一试还是当头一棒,毕竟还是对arm asm不太熟悉的结果,反而是磕磕碰碰的不太顺利,不过好歹还是搞清楚了。
        其间还一度对arm的设计产生的怀疑,不过最后看来看去还是发现arm asm的功能啊什么的还是很8错的,哈哈。

        自己做一个能够有易于使用的,能够在arm linux平台上在kernel和user space都可用的监视寄存器值的手段,就出了一个不算完善的东东,有些东西也是复习复习,也还没有测试完善,在kernel中使用的话可能还有些需要修改的东西吧。暂时收录起来:



        使用的时候可以把宏放到一个头文件里面就可以直接使用了。现在还有一点不爽的就是还需要一个特定数据类型的变量作为宏的参数传入,如果传入的数据类型长度小于所位于的平台的位数,就会产生“令人迷惑的结果”。所以使用的时候依赖于不同的平台了。对于arm,传入的参数的类型最好还是:unsigned long吧。如果定义成u32或者u64等等也行,只要和reg的长度相符合就可以了。

        同样,在编译的时候加上优化的参数:-O(默认的优化级别似乎就是2,当然禁止优化就用-O0了。哈哈)。
           1.如果是为了调试用的话,加上-g可能会有更好的效果。
           2.似乎-finline-functions也是不太令人欢迎的选项。

        嗯,大概就是这些吧,如果在kernel中使用的话,可以做成一个module,或者就是一个头文件就搞定,等下一阶段如果要调试kernel module的时候有用到再说了。

        收工看书去也。

    展开全文
  • 数据打印输出(寄存器方式) 最近在运用操作系统过程中,遇到一个问题,就是当2个任务函数同时调用一个hal库函数时,会发生异常情况,导致数据输出存在bug。经过一番检查之后,发现可能是库函数调用过程中,相关...
  • arm中在代码中获取寄存器

    千次阅读 2011-07-14 17:09:52
    uint32* cur_sp = 0, *cur_lr = 0, *cur_pc = 0; #ifndef __ARMCC_VERSION > 22000 #pragma arm  __asm { ... 寄存器。 __current_sp() 访问  sp  寄存器。 __return_address() 访问  lr  寄存器
  • c语言经典案例

    2014-10-30 08:06:57
    实例263 获取寄存器信息 405 第17章 图形图像处理 407 实例264 绘制直线 408 实例265 绘制矩形 409 实例266 绘制表格 411 实例267 绘制立体窗口 412 实例268 绘制椭圆 414 实例269 绘制圆弧线 415 实例270 绘制扇区 ...
  • gdb没有CodeWarrior强大,但是也提供了查看寄存器的命令:(gdb) info register r1r1 0xbffffb40 32212242...
  • 在发送stack corruption时,可以通过sp在c中监控stack的数值 Linux 内核中对特殊寄存器的读取 #define read_sysreg(r) ({ \ u64 __val; \ asm volatile("mrs %0, " __stringify(r) : "=r" (__val)); \ __val; \...
  • 海思寄存器操作

    千次阅读 2019-06-21 09:31:59
    转载地址:https://blog.csdn.net/weixin_38239856/article/details/80856781 如何查看和修改寄存器 在程序中可以使用HI_SYS_ReadRe...
  • C语言--输入地址,输出该地址内容

    千次阅读 2020-11-26 21:55:00
    目标 输入一个内存地址,输出该内存地址的内容 代码及测试 unsigned int temp = 4; printf("%d\n", &temp);...(2)打印该变量的地址,十进制显示 (3)定义一个地址变量address (4)..
  • 寄存器以16进制显示,程序如下:.section .bbs .lcomm buf,10 #定义一个10字节长度的内存区,用来储存计算出来的字符 .section .text .globl _start _start: //初始化寄存器 movl $0x01abcdef,%eax #将需要...
  • 特别是,C语言中的整数类型可表示不同的取值范围和正负。一般情况使用int类型即可,但是为满足特定任务和机器的要求,还可以选择其他类型。int类型是有符号整型,即int类型的必须是整数,可以是正整数、负整数或...
  • //打印各元素的地址 return 0; } 结果:13629376 13629376 13629380 13629384 13629388 13629392 验证可知,数组在内存中连续存放,每个元素数据类型相同 数组名 像const修饰的变量不可以改变,也就是说这种变量...
  • 原创作品转载请注明出处 ...我们在这里从汇编代码的角度, 给出一段简单的C语言程序运行过程中机器状态的变化情况. 我们的实验环境是Ubuntu 64位, 编译器gcc的版本是4.8.4. 我们使用的c程序如下: ...
  • 大小端、%u、%d打印的规则、数据在内存中的存储 目录 文章目录大小端、%u、%d打印的规则、数据在内存中的存储数据在内存中的存储整形存储无符号整型、无符号整型的打印char类型的打印浮点型存储大小端模式判断机器...
  • c语言中变量分为四类,分别是 1.auto 自动变量 2.static 静态存贮分配变量(又分为内部静态和外部静态) 3.extern 全程变量(用于外部变量说明) 4.register 寄存器变量(分配在硬件...
  • C语言中的四种存储类别: 自动变量 (auto)、静态变量(static)、寄存器(register)、外部变量 (extern)。 1. 自动变量 通常在自定义函数内或代码段中(用“{}”括起来的)定义的变量,都是自动变量,除了加...
  • 下方就是通过p命令将r1寄存器中所存的内容进行打印,在打印之前将r1进行类型转换,po命令则输出了Objective-C的对象,而p输出的是C语言类型的数据。如下所示: (lldb) po $r0 (lldb) p (char *)$r1 (char *) $1 = 0x...
  • C语言基础知识入门(大全)

    万次阅读 多人点赞 2021-05-11 18:34:11
    一.C语言入门 C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效率高而且可移植性好,可以用来开发应用软件、驱动、操作系统等。C语言也是其它众多高级...
  • 前言本文翻译自Assembly Register Calling Convention Tutorial 序言通过本教程,你会可以看到CPU使用的寄存器,并探索和修改传递给函数调用的参数。还将学习常见的苹果计算机架构以及如何在函数中使用寄存器。这...
  • C语言讲义.doc

    2018-01-27 10:41:43
    2.10.2 printf输出int 23 2.10.3 printf输出八进制和十六进制 23 2.10.4 short,long,long long,unsigned int 23 2.10.5 整数溢出 23 2.10.6 大端对齐与小端对齐 23 2.11 CHAR类型 24 2.11.1 char常量,变量 24 ...
  • 【C/C++】C语言特性总结

    万次阅读 多人点赞 2019-08-10 16:21:28
    已经有大约半年的时间没有碰C语言了,当时学习的时候记录了很多的笔记,但是都是特别混乱,后悔那个时候,不懂得写博客,这里凭借记忆和零零散散的笔记记录,尝试系统性地复习一下C语言。 之前都是在Windows环境下...
  • C语言面试基础知识之一

    万次阅读 多人点赞 2018-03-31 11:21:46
    C语言中,关键字static有三个明显的作用:1). 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其不变。2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被...
  • xcode 打印内存中的

    千次阅读 2017-11-07 19:34:47
    所以许多时候需要调试原始的C语言指针。Xcode的调试器LLDB提供了许多有趣的调试指令,下面来看看针对内存数据的读取和修改指令。为了更好地演示,先写一段测试代码,如下:int ints[] = {1, 2, 3}; double doubles...
  • verilog 入门教程

    万次阅读 多人点赞 2014-06-16 11:14:01
    这些也能够用于与期望比较,在不匹配的情况下,打印报告消息。  (16)在行为级描述中,Verilog HDL 不仅能够在 RTL 级上进行设计描述,而且能够在体系结构级描述及其算法级行为上进行设计描述。  (17...
  • 现在我们来简单介绍一下在c语言中的常见的数据类型以及它们的范围: char //字符数据类型 short //短整型 int //整形 long //长整型 long long //更长的整形 float //单精度浮点数 double //双精度浮点数 类型的...
  • C语言函数调用栈(一)

    万次阅读 多人点赞 2018-07-19 22:16:25
    编译器使用堆栈传递函数参数、保存返回地址、临时保存寄存器原有(即函数调用的上下文)以备恢复以及存储本地局部变量。 不同处理器和编译器的堆栈布局、函数调用方法都可能不同,但堆栈的基本概念是一...
  • C++register寄存器变量 变量除了数据类型以外,还有3种属性: 存储类别,C++允许使用auto,static,register和extern4种存储类别。 作用域,指程序中可以引用该变量的区域。 存储期,指变量在内存的存储期限。 auto, ...
  • c语言printf问题(a++,++a,--a,a--)

    千次阅读 2020-07-16 10:32:14
    c语言printf函数处理输出参数如何处理 举例: #include<stdio.h> int main() { int i = 0; printf("%d,%d,%d\n", --i, --i, i++); } 有人会认为打印结果为:0,0,-1 但实际打印结果为: 相信大家都...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,855
精华内容 6,742
关键字:

c语言打印寄存器的值

c语言 订阅