资料介绍
14.4 布尔表达式
14.4.1 范围检测
通常,布尔表达式被用来检测某个数值是否在特定的范围内。例如,在图形窗口处理程序中,常使用布尔表达式判断屏幕中一个点是否在当前活动窗口范围内。
下面的程序使用结构体定义点坐标并计算坐标的当前位置。
bool PointInRect1(Point p, Rectangle *r)
{ return (p.x 》= r-》xmin && p.x 《 r-》xmax &&
p.y 》= r-》ymin && p.y 《 r-》ymax);
}
上面的功能函数,被编译为下面的指令序列。
PointInRect1
LDR a4,[a3,#0]
CMP a1,a4
BLT |L000034.J5.PointInRect1|
LDR a4,[a3,#4]
CMP a4,a1
BLE |L000034.J5.PointInRect1|
LDR a1,[a3,#8]
CMP a2,a1
BLT |L000034.J5.PointInRect1|
LDR a1,[a3,#&c]!
CMP a2,a1
MOVLT a1,#1
MOVLT pc,lr
|L000034.J5.PointInRect1|
MOV a1,#0
MOV pc,lr
但上面的代码并不是最精简的。编译器对(x 》= min && x 《 max)形式的布尔表达式的处理过程比较复杂。它将以(unsigned)(x-min) 《 (max-min)形式实现布尔操作。所有对于上面范围判断的代码,建议将函数写成如下形式。
bool PointInRect2(Point p, Rectangle *r)
{ return ((unsigned) (p.x - r-》xmin) 《 r-》xmax &&
(unsigned) (p.y - r-》ymin) 《 r-》ymax);
}
这样编译出的汇编指令序列如下所示。
PointInRect2
LDR a4,[a3,#0]
SUB a1,a1,a4
LDR a4,[a3,#4]
CMP a1,a4
LDRCC a1,[a3,#8]
SUBCC a1,a2,a1
LDRCC a2,[a3,#&c]!
CMPCC a1,a2
MOVCS a1,#0
MOVCC a1,#1
MOV pc,lr
14.4.2 和零的比较操作
比较指令(CMP)将设置程序状态字的条件标志位。另外,基本的算术指令也可以设置条件标志位,如使用指令MOVS、ADDS等。如果程序中的算术指令的执行目的是为了将计算结果和零比较,那么就可以直接使用带标志扩展的基本算术指令。如下面的两条语句:
ADD R0, R0, R1
CMP R0, #0
可以合并为一条带符号扩展的加法指令:
ADDS R0, R0, R1
事实上,C语言中的和零相关的关系操作都可以利用状态标志寄存器的N位和Z位。如:x 《 0, x 》= 0, x = 0, x != 0,和无符号操作x = 0, x != 0 (or x 》 0)。
对于每一条C语言中的关系操作,汇编器都将产生一条比较指令。如果关系操作和零相关,则可以将产生的比较指令移除。
下面是C语言中的关系操作被编译的例子。
C源文件如下所示。
int g(int x, int y)
{
if ((x + y) 《 0)
return 1;
else
return 0;
}
编译后的结果如下。
g
ADDS a1,a1,a2
MOVPL a1,#0
MOVMI a1,#1
MOV pc,lr
所以,在使用C语言编程时,关系操作最好转换成和零相关的,这样既可以减少代码密度,也可以提高程序的执行效率。
C语言中,没有和程序状态寄存器的C位和V位直接相关的指令,所以要在程序中检测这些标志,只能使用内嵌汇编。但C编译器支持无符号溢出操作,下面的例子显示了在有溢出操作时,编译器对程序的处理。
C源代码如下所示。
int sum(int x, int y)
{
int res;
res = x + y;
if ((unsigned) res 《 (unsigned) x) /* 判断进位标志是否进位 */
res++;
return res;
}
编译的汇编文件如下所示。
sum
ADDS a2,a1,a2
ADC a2,a2,#0
MOV a1,a2
MOV pc,lr
14.4.1 范围检测
通常,布尔表达式被用来检测某个数值是否在特定的范围内。例如,在图形窗口处理程序中,常使用布尔表达式判断屏幕中一个点是否在当前活动窗口范围内。
下面的程序使用结构体定义点坐标并计算坐标的当前位置。
bool PointInRect1(Point p, Rectangle *r)
{ return (p.x 》= r-》xmin && p.x 《 r-》xmax &&
p.y 》= r-》ymin && p.y 《 r-》ymax);
}
上面的功能函数,被编译为下面的指令序列。
PointInRect1
LDR a4,[a3,#0]
CMP a1,a4
BLT |L000034.J5.PointInRect1|
LDR a4,[a3,#4]
CMP a4,a1
BLE |L000034.J5.PointInRect1|
LDR a1,[a3,#8]
CMP a2,a1
BLT |L000034.J5.PointInRect1|
LDR a1,[a3,#&c]!
CMP a2,a1
MOVLT a1,#1
MOVLT pc,lr
|L000034.J5.PointInRect1|
MOV a1,#0
MOV pc,lr
但上面的代码并不是最精简的。编译器对(x 》= min && x 《 max)形式的布尔表达式的处理过程比较复杂。它将以(unsigned)(x-min) 《 (max-min)形式实现布尔操作。所有对于上面范围判断的代码,建议将函数写成如下形式。
bool PointInRect2(Point p, Rectangle *r)
{ return ((unsigned) (p.x - r-》xmin) 《 r-》xmax &&
(unsigned) (p.y - r-》ymin) 《 r-》ymax);
}
这样编译出的汇编指令序列如下所示。
PointInRect2
LDR a4,[a3,#0]
SUB a1,a1,a4
LDR a4,[a3,#4]
CMP a1,a4
LDRCC a1,[a3,#8]
SUBCC a1,a2,a1
LDRCC a2,[a3,#&c]!
CMPCC a1,a2
MOVCS a1,#0
MOVCC a1,#1
MOV pc,lr
14.4.2 和零的比较操作
比较指令(CMP)将设置程序状态字的条件标志位。另外,基本的算术指令也可以设置条件标志位,如使用指令MOVS、ADDS等。如果程序中的算术指令的执行目的是为了将计算结果和零比较,那么就可以直接使用带标志扩展的基本算术指令。如下面的两条语句:
ADD R0, R0, R1
CMP R0, #0
可以合并为一条带符号扩展的加法指令:
ADDS R0, R0, R1
事实上,C语言中的和零相关的关系操作都可以利用状态标志寄存器的N位和Z位。如:x 《 0, x 》= 0, x = 0, x != 0,和无符号操作x = 0, x != 0 (or x 》 0)。
对于每一条C语言中的关系操作,汇编器都将产生一条比较指令。如果关系操作和零相关,则可以将产生的比较指令移除。
下面是C语言中的关系操作被编译的例子。
C源文件如下所示。
int g(int x, int y)
{
if ((x + y) 《 0)
return 1;
else
return 0;
}
编译后的结果如下。
g
ADDS a1,a1,a2
MOVPL a1,#0
MOVMI a1,#1
MOV pc,lr
所以,在使用C语言编程时,关系操作最好转换成和零相关的,这样既可以减少代码密度,也可以提高程序的执行效率。
C语言中,没有和程序状态寄存器的C位和V位直接相关的指令,所以要在程序中检测这些标志,只能使用内嵌汇编。但C编译器支持无符号溢出操作,下面的例子显示了在有溢出操作时,编译器对程序的处理。
C源代码如下所示。
int sum(int x, int y)
{
int res;
res = x + y;
if ((unsigned) res 《 (unsigned) x) /* 判断进位标志是否进位 */
res++;
return res;
}
编译的汇编文件如下所示。
sum
ADDS a2,a1,a2
ADC a2,a2,#0
MOV a1,a2
MOV pc,lr
下载该资料的人也在下载
下载该资料的人还在阅读
更多 >
- Oracle中常用的函数与表达式讲解
- 基于运算符信息的数学表达式检索技术 2次下载
- Python正则表达式指南 10次下载
- LabVIEW之表达式节点、公式节点和公式VI 23次下载
- Python正则表达式的学习指南 0次下载
- C语言指针的表达式实例程序说明 4次下载
- C++程序设计教程之数据类型与表达式的详细资料说明 0次下载
- C语言实用教程之数据类型运算符和表达式的详细资料说明 10次下载
- C++入门教程之数据类型、运算符和表达式的详细资料说明 2次下载
- Python正则表达式教程之标准库的完整介绍及使用示例说明 3次下载
- C语言教程之C语言中级培训教程—何谓表达式 0次下载
- 如何编写C语言代码中的乘法正确表达式详细概述 4次下载
- C语言程序设计--运算符与表达式
- 防范表达式的失控
- 基因表达式编程的2种解码方法
- GVIM正则表达式介绍和使用示例 1357次阅读
- 什么是正则表达式?正则表达式如何工作?哪些语法规则适用正则表达式? 3819次阅读
- Java Lambda表达式的新特性 2618次阅读
- OpenHarmony中使用正则表达式 1506次阅读
- shell脚本基础:正则表达式grep 1285次阅读
- Python中的Lambda表达式 851次阅读
- 位逻辑运算符与表达式 1284次阅读
- 逻辑运算符与表达式 2205次阅读
- C语言的表达式 1405次阅读
- 表达式与逻辑门之间的关系 1662次阅读
- 运算符/表达式规则 1032次阅读
- RTL表达式和运算符 1793次阅读
- C语言如何使用正则表达式 4970次阅读
- 教你如何轻松搞定Linux正则表达式 3645次阅读
- 快速入门IPv6和正则表达式 9051次阅读
下载排行
本周
- 1电子电路原理第七版PDF电子教材免费下载
- 0.00 MB | 1490次下载 | 免费
- 2单片机典型实例介绍
- 18.19 MB | 92次下载 | 1 积分
- 3S7-200PLC编程实例详细资料
- 1.17 MB | 27次下载 | 1 积分
- 4笔记本电脑主板的元件识别和讲解说明
- 4.28 MB | 18次下载 | 4 积分
- 5开关电源原理及各功能电路详解
- 0.38 MB | 10次下载 | 免费
- 6基于AT89C2051/4051单片机编程器的实验
- 0.11 MB | 4次下载 | 免费
- 7蓝牙设备在嵌入式领域的广泛应用
- 0.63 MB | 3次下载 | 免费
- 89天练会电子电路识图
- 5.91 MB | 3次下载 | 免费
本月
- 1OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234313次下载 | 免费
- 2PADS 9.0 2009最新版 -下载
- 0.00 MB | 66304次下载 | 免费
- 3protel99下载protel99软件下载(中文版)
- 0.00 MB | 51209次下载 | 免费
- 4LabView 8.0 专业版下载 (3CD完整版)
- 0.00 MB | 51043次下载 | 免费
- 5555集成电路应用800例(新编版)
- 0.00 MB | 33562次下载 | 免费
- 6接口电路图大全
- 未知 | 30320次下载 | 免费
- 7Multisim 10下载Multisim 10 中文版
- 0.00 MB | 28588次下载 | 免费
- 8开关电源设计实例指南
- 未知 | 21539次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935053次下载 | 免费
- 2protel99se软件下载(可英文版转中文版)
- 78.1 MB | 537791次下载 | 免费
- 3MATLAB 7.1 下载 (含软件介绍)
- 未知 | 420026次下载 | 免费
- 4OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234313次下载 | 免费
- 5Altium DXP2002下载入口
- 未知 | 233045次下载 | 免费
- 6电路仿真软件multisim 10.0免费下载
- 340992 | 191183次下载 | 免费
- 7十天学会AVR单片机与C语言视频教程 下载
- 158M | 183277次下载 | 免费
- 8proe5.0野火版下载(中文版免费下载)
- 未知 | 138039次下载 | 免费
评论
查看更多