程序如下,第一种方式是强制指针转换,再取结构体成员;第二种方式是简单的移位。前面这种写法得考虑大小端序, 后者不用管.

#include <stdio.h>#define hi8(x)    ((( struct { unsigned char l; unsigned char h; } *)(&x))->h)
#define lo8(x)    ((( struct { unsigned char l; unsigned char h; } *)(&x))->l)
#define hi8a(x)    (((x) >> 8) & 0xff)
#define lo8a(x)    ((x) & 0xff)int main(void)
{unsigned short x;scanf("%4x", &x);                     // 不能用字面量测试, 否则-Os编译时会直接给求值了printf("%2X %2Xn", hi8(x), lo8(x));printf("%2X %2Xn", hi8a(x), lo8a(x));return 0;
}

分别用mingw-gcc, arm-none-eabi-gcc, -O0和-Os选项编译,得到的汇编如下(只取scanf到第二次printf之间的部分)

mingw-gcc, -O0, 前者9条指令, 后者10条指令. 有点呆萌是吧...

  call    _scanflea   eax, [esp+30]movzx eax, BYTE PTR [eax]movzx    edx, allea  eax, [esp+30]movzx eax, BYTE PTR [eax+1]                   ; 这里错开1字节取值movzx   eax, almov  DWORD PTR [esp+8], edxmov  DWORD PTR [esp+4], eaxmov  DWORD PTR [esp], OFFSET FLAT:LC1      ; LC1是printf的格式字符串call    _printfmovzx    eax, WORD PTR [esp+30]movzx    eax, axmovzx    edx, almovzx    eax, WORD PTR [esp+30]shr  ax, 8                      ; 移位movzx    eax, axmovzx    eax, almov  DWORD PTR [esp+8], edxmov  DWORD PTR [esp+4], eaxmov  DWORD PTR [esp], OFFSET FLAT:LC1call    _printf

mingw-gcc, -Os, 前者5条指令, 后者6条指令.

    call    _scanfmovzx eax, BYTE PTR [esp+30]mov  DWORD PTR [esp], OFFSET FLAT:LC1   ; 常量入栈提到前面了mov   DWORD PTR [esp+8], eaxmovzx    eax, BYTE PTR [esp+31]               ; 取值错开1字节mov  DWORD PTR [esp+4], eaxcall _printfmov  ax, WORD PTR [esp+30]mov   DWORD PTR [esp], OFFSET FLAT:LC1movzx   edx, almovzx    eax, ah                          ; 这次把移位优化掉了, 直接利用ax寄存器的高低位.mov DWORD PTR [esp+8], edxmov  DWORD PTR [esp+4], eaxcall _printf

arm-none-eabi-gcc, -O0, 前者8条指令, 后者10条指令:

   bl  scanfsub    r3, fp, #6ldrb  r3, [r3, #1]    @ zero_extendqisi2mov  r2, r3sub   r3, fp, #6ldrb  r3, [r3]    @ zero_extendqisi2           ; 错开1字节ldr    r0, .L3+4                     ; .L3+4是printf的格式字符串mov r1, r2mov   r2, r3bl    printfldrh  r3, [fp, #-6]mov    r3, r3, lsr #8mov   r3, r3, asl #16mov  r3, r3, lsr #16and  r2, r3, #255ldrh    r3, [fp, #-6]and    r3, r3, #255ldr r0, .L3+4mov   r1, r2mov   r2, r3bl    printf

arm-none-eabi-gcc, -Os, 这个清爽多了, 前者3条指令, 后者4条指令.

 bl  scanfldrb   r1, [sp, #7]    @ zero_extendqisi2ldrb r2, [sp, #6]    @ zero_extendqisi2    ; 错开1字节mov   r0, r4                   ; .L3+4被提前放进r4了bl printfldrh  r1, [sp, #6]mov r0, r4mov   r1, r1, lsr #8             ; 移位ldrb r2, [sp, #6]    @ zero_extendqisi2bl   printf

avr-gcc呢, 太长就不贴了. 不过-Os时反倒是移位方式的指令更少.

总之以上四种情况都是前者好些. 不过实际运行时也不一定, 没准后者更快呢?

----------------2020.2.22补充-------------------

还有一个重要的区别:前者可以作为左值,后者不行。

如下程序:

#include <stdio.h>#define hi8(x)    ((( struct { unsigned char l; unsigned char h; } *)(&x))->h)
#define lo8(x)    ((( struct { unsigned char l; unsigned char h; } *)(&x))->l) int main(void)
{unsigned short x = 0x1234;hi8(x)--;lo8(x)++;printf("%xn", x);return 0;
}

运行,结果是1135。

lcd取模如何取16位_两种方式实现取16位变量的高低8位, 不严谨对比相关推荐

  1. 取pi的前8位的解压密码_两种方式实现取16位变量的高低8位, 不严谨对比

    程序如下,第一种方式是强制指针转换,再取结构体成员:第二种方式是简单的移位.前面这种写法得考虑大小端序, 后者不用管. #include <stdio.h>#define hi8(x) ( ...

  2. java excel生成_两种方式实现java生成Excel

    Web应用中难免会遇到需要将数据导出并生成excel文件的需求.同样,对于本博客中的总结,也是建立在为了完成这样的一个需求,才开始去了解其实现形式,并且顺利完成需求的开发,先将实现过程总结于此.本博文 ...

  3. windbg-获取结构体大小(常用的两种方式)

    两种方式: dt -v:详细输出.这会输出结构的总大小和字段数量这样的附加信息.当它和-y选项一起使用时,所有的符号都会被显示出来,即使他们没有任何关联的类型信息. [cpp] view plainc ...

  4. python网络通信的几种方式_两种方式,java=python,使用py4j进行通信

    我使用py4j实现python和java之间的通信,能够从java端调用python方法.但从python我不能发送任何对象或调用java方法.这是我试过的密码.在 我的java代码:public i ...

  5. 多个相机拍摄定位_两种方式拍照易泄露隐私 | 如何避免照片记录 iPhone 定位信息?...

    一直以来,AirDrop 都是苹果生态圈的优势,可以在不同设备间快速传输文件.AirDrop 传输图片时还会保留原有的 Exif 数据,虽然一定程度上保证了土拍你的完整性,但另一方面也会造成隐私信息泄 ...

  6. 口腔取模过程及注意事项_康贝齿科首家引进LAUNCA数字化口腔扫描,走进口腔数字化诊疗时代!...

    口腔领域中的数字化技术包括数字化印模.数字化诊断与治疗.数字化生产.数字化手术导航.影像学以及相关材料的应用等. 20世纪70年代Duret医生将工业数字化生产技术应用于口腔临床工作的大胆设想,使口腔 ...

  7. 快递取件码生成软件_一种分布式的取件码生成方法技术

    [技术实现步骤摘要] 本专利技术涉及样品柜取件码生成 ,特别涉及一种分布式的取件码生成方法. 技术介绍 在快递柜的领域中,快递员进行快件派送的时候,通常会遇到收件人无法立刻来取件的情况,这样就需要快递 ...

  8. 微博社交内容信息爬取(selenium和equests请求接口两种方法)

    总体目标:抓取微博内容信息:给一个入口,抓分布抓取关注list,然后给到具体链接去爬取具体个人的微博信息 #我这现在有两种方式,selenium模拟登陆和下拉,二是分析接口获取具体微博信息,这边暂时没 ...

  9. 两种方式对boss直聘招聘岗位的爬取

    上次留了个坑,采取两种方式对需要爬取的网站进行数据抓取.首先使用selenium+chromedriver进行抓取,这种方式速度慢,但是可以跳过各种反爬设置,并对各种反爬能够直接以网页的形式进行显示. ...

最新文章

  1. 双轴机械臂建模分析数据
  2. 批量消除图片的杂色背景
  3. 轻松监听Azure service health 状态
  4. linux中常用安装程序的方法,Linux下常见的软件安装方式
  5. 学python语言有前途吗-学习python的前景怎么样?
  6. 使用软件测试工具WinRunner的几点建议
  7. 3D建模、处理软件及部分算法库简介
  8. QQ浏览器+7654联盟
  9. php获取openid 40163报错,微信支付授权获取 openId {\errcode\:40163,\errmsg\:\code been used, hints: [ req_id:...
  10. Java调用SharePoint WebService获取文件和文件夹
  11. 45句绝美宋词,哪一句触动了你?
  12. 看古人如何养颜:散落在历史中的美容秘方
  13. 2017年武昌工学院计算机基础,武昌理工学院2017.doc
  14. python-探索性数据分析-足球赛事数据集
  15. 不经一番寒彻骨,怎得梅花扑鼻香,墙都不扶就服你
  16. php中文日期转成date类型,php怎么将含中文的日期转为时间戳
  17. 新手安装R以及Rstudio软件
  18. 遗传算法之旅行家问题(TSP)
  19. 无盘服务器配置网众,网众无盘服务端工作站设置
  20. 裕太微在科创板上市:市值约186亿元,哈勃科技和小米基金为股东

热门文章

  1. java基础格式_Java基础之代码的基本格式
  2. 1.计算机技术在音乐作品中的使用,数字技术在电子音乐中的应用论文
  3. 为项目添加autoprefixer
  4. PCL:PCL1.9.0更新
  5. 图像的全局特征--用于目标检测
  6. 在MFC中使用Cstring
  7. Win7共享文件夹简单?这个共享问题可以难倒90%的人
  8. 为什么我们对90后的迎合难以成功?
  9. windows下看端口占用
  10. Mysql 架构及优化之-索引优化