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

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

#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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/245097.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java实现的小程序_Java实现 微信小程序 + 消息推送

实现效果&#xff1a;下面要显示五个字段接下来&#xff0c;参照官方文档&#xff0c;一步步实现&#xff1a;一、官方给出请求示例、返回示例二、根据上面编写实体类(1)请求参数Datapublic class SendTemplateReq {/*** 接收者(用户)的 openid*/private String touser;/*** 所…

vb excel 整行删除_Excel中常用的批量处理都不掌握,那就真的Out了

针对一些有规律&#xff0c;能批量处理的数据&#xff0c;必须采用批量处理的方法&#xff0c;否则对于工作效率就会有很大的影响。今天我们来学习的内容是Excel中的6个批量处理技巧。一、Excel批量技巧&#xff1a;批量求和。目的&#xff1a;按照“季度”和“产品”两个维度计…

eclipse找不到dynamic_Eclipse Juno在Dynamic Web Project中没有JSP(但其他...

简短的问题是,在创建动态Web项目(1.6 jdk)时,我可以看到要创建的所有文件类型,但jsp没有选项.当我检查文件关联时添加到那里,没有可供选择的JSP编辑器.稍微长一点的版本是我只想编辑JSP文件,我安装了Juno EE版本,它说安装了Web工具平台,一切正常.然而,虽然一切正常,但文件关联中…

exe编辑器_【小功能】Unreal Editor中调用exe

后续文章更新移步→微信公众号“虚幻社区”&#xff08;mantra-xhsq&#xff09;&#xff0c;您的支持是我创作的动力。在程序界混&#xff0c;哪能碰上不改需求的策划 --Mantra最近遇到了一个奇葩的需求&#xff0c;在Unreal Editor的Toolbar中添加一个快捷键&#xff0c;可以…

java bitset用途_BitSet的用法

1&#xff0c;BitSet类大小可动态改变, 取值为true或false的位集合。用于表示一组布尔标志。此类实现了一个按需增长的位向量。位 set 的每个组件都有一个 boolean 值。用非负的整数将 BitSet 的位编入索引。可以对每个编入索引的位进行测试、设置或者清除。通过逻辑与、逻辑或…

html select选择事件_按键精灵的Html系列命令实战讲解

金猪脚本(原飞猪脚本)以按键精灵教学为主,涉及UiBot&#xff0c;Python,Lua等脚本编程语言,教学包括全自动办公脚本,游戏辅助脚本,引流脚本,网页脚本,安卓脚本,IOS脚本,注册脚本,点赞脚本,阅读脚本以及网赚脚本等各个领域。想学习按键精灵的朋友可以添加金猪脚本粉丝交流群:554…

java多线程意义_Java多线程学习之多线程的概念及意义

Java的线程机制&#xff0c;则是由执行程序表示的单一进程创建的任务(拗口&#xff01;)&#xff0c;注意&#xff0c;是在单一进程里面创建多个任务&#xff0c;不同于操作系统分叉外部进程。由于所有的任务在同一个进程内&#xff0c;任务之间会相互干涉(例如操作同样的对象&…

java 验证码_java学习之web基础(6):使用Response的输出流在页面输出验证码

package 输出并且我们可以写一个简单的网页&#xff0c;来实现点击更新验证码<!DOCTYPE html>

java socket编程实现聊天程序_java Socket编程 聊天程序 服务器端和客户端

[java]代码库package com.gufengxiachen.sthreadchatapp;/*** author GUXIA*/import java.io.BufferedReader;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;imp…

电商前台模板中文html5_跨境电商平台上产品如何上传?虾皮新版批量上传工具使用指南分享...

大家好&#xff0c;这里是天师跨境&#xff0c;今天来为电商新人们解答一下关于如何在跨境电商平台上上传产品的疑惑&#xff0c;顺便介绍一下虾皮跨境平台的新版批量上传工具是如何使用的。在跨境电商平台上开店的新手们在入驻成功后&#xff0c;一般最先面临的问题就是上传产…

移动端 关闭浏览器事件_前端开发中什么是移动端点透事件?

点透事件&#xff1a;是指两个元素其中一个元素具有默认的点击事件&#xff0c;当我们让不具有点击事件的元素隐藏起来&#xff0c;会触发另一个元素的点击事件&#xff0c;这种行为被称之为点透事件。如下图所示&#xff1a;当我们给div元素添加touchstart事件让div元素隐藏起…

java web 线程数_Java Web应用调优线程池

最简单的单线程我们先从基础开始。无论使用哪种应用服务器或者框架(如Tomcat、Jetty等)&#xff0c;他们都有类似的基础实现。Web服务的基础是套接字(socket)&#xff0c;套接字负责监听端口&#xff0c;等待TCP连接&#xff0c;并接受TCP连接。一旦TCP连接被接受&#xff0c;即…

清除浏览器缓存之后为什么还是显示旧的html页面_Web缓存控制策略详解

管理Web缓存的最常用和最有效的方法之一是通过Cache-Control HTTP标头&#xff0c;由于此标头适用于Web页面的缓存&#xff0c;这意味着我们页面上的所有内容都可以具有非常精细化的缓存策略。通过各种自定义策略&#xff0c;我们控制的策略就可以变得非常复杂和强大。Cache-Co…

js二维数组_Javascript数组

数组的概念&#xff1a;引用类型的对象。本质&#xff1a;内存中存储多个数据的空间&#xff0c;再取个名字。数据结构&#xff1a;数据结构不同&#xff0c;擅长的操作不同。数组特点&#xff1a;便于数据的查找与维护。数组的创建&#xff1a;方法1&#xff1a;var 数组名【元…

java jtextfield 事件_JAVA JTextField事件处理

初学JAVA&#xff0c;笔记&#xff1a;package windows;import javax.swing.*;import java.awt.*;import java.awt.event.*;class WindowFlow extends JFrame implements ActionListener{private static final long serialVersionUID 1L;JTextField text1,text2;WindowFlow(St…

js封装函数_JavaScript基础-如何封装函数来改变元素的位置

点击右上方红色按钮关注“小郑搞码事”&#xff0c;每天都能学到知识&#xff0c;搞懂一个问题&#xff01;大家好&#xff01;我是/小郑搞码事/的小郑今天给大家分享JavaScript的基础知识-改变元素的位置。没错&#xff0c;用JS实现过动画的同学都应该了解一点&#xff0c;简单…

python查找指定字符所在行号_python查找字符串中某个字符

本文收集整理关于python查找字符串中某个字符的相关议题&#xff0c;使用内容导航快速到达。内容导航&#xff1a;Q1&#xff1a;Python里统计一个字符串中另一个字符串的个数答案为3(用正则)&#xff1a;1234>>>importre>>>sabababab>>>len(re.fin…

java jai create 方法_使用JAI扩展Java Image的功能

Java Image功能一直都在增强&#xff0c;但是向磁盘写一个图像文件或者返回一个PNG或JPEG依然比较难实现。但是我们可以使用Java Advanced Imaging(JAI)API来解决这个问题。JAI可以从SUN的Java站点下载&#xff0c;它包含在JDK 1.4的javax.imageio包中。要安装JAI&#xff0c;你…

python实现rm_python winrm模块使用

使用session方法###import winrmswinrm.Session(http://10.10.60.14:5985/wsman,auth(administrator,password))rs.run_ps(dir)rs.run_cmd(cd /d d: & test.bat)print r.std_outprint r.std_err使用Protocol方法###import winrmconn winrm.Protocol(endpointhttp://10.10…

java程序设计与实践教程 王薇 doc_Java程序设计与实践教程 王薇主编 答案

Java程序设计与实践教程 王薇 主编 董迎红 副主编 课后习题 答案第1章 JAVA简介一、判断题1.√ 2.√ 3. 4. 5. 6.√ 7.√ 8.√ 9. 10.二、填空题1.Application Applet 2. 类(字节码文件、目标文件) .class3.对象 4. 主 5. J2SE J2EE J2ME三、选择题1.B 2. D 3.B 4.B 5. A四、简…