【C语言】有符号和无符号数的比较运算

	int a = -1;
	unsigned int b = 1;
	if(a < b)
		printf("a < b\r\n");
	else
		printf("a > b\r\n");
	
	if(a < (int)b)
		printf("a < b\r\n");
	else
		printf("a > b\r\n");

运行结果:

a > b
a < b

直接比较a和b的话,a会被当做是0xFFFFFFFF来和b比较,因此a>b,而强制类型转换b为int类型时,才能得到正确结果。

将程序反汇编看看到底为什么:

0x08002CC2 F04F35FF  MOV      r5,#0xFFFFFFFF
    58:         unsigned int b = 1; 
0x08002CC6 2401      MOVS     r4,#0x01
    59:         if(a < b) 
0x08002CC8 42A5      CMP      r5,r4
0x08002CCA D203      BCS      0x08002CD4
    60:                 printf("a < b\r\n"); 
    61:         else 
0x08002CCC A029      ADR      r0,{pc}+4  ; @0x08002D74
0x08002CCE F7FDFB03  BL.W     __2printf (0x080002D8)
0x08002CD2 E002      B        0x08002CDA
    62:                 printf("a > b\r\n"); 
    63:          
0x08002CD4 A029      ADR      r0,{pc}+4  ; @0x08002D7C
0x08002CD6 F7FDFAFF  BL.W     __2printf (0x080002D8)
    64:         if(a < (int)b) 
0x08002CDA 42A5      CMP      r5,r4
0x08002CDC DA03      BGE      0x08002CE6
    65:                 printf("a < b\r\n"); 
    66:         else 
0x08002CDE A025      ADR      r0,{pc}+2  ; @0x08002D74
0x08002CE0 F7FDFAFA  BL.W     __2printf (0x080002D8)
0x08002CE4 E002      B        0x08002CEC
    67:                 printf("a > b\r\n"); 

可以看到 “if(a < b)” 和 “if(a < (int)b)” 都被编译成了 “CMP r5,r4” ,但是下面的判断语句有区别,ARM指令集中B指令是跳转指令,后面跟着跳转条件,可以看到 “if(a < b)”的跳转条件为 “CS” ,而 “if(a < (int)b)” 的跳转条件为 “GE”,这就是区别所在,下面进行简单分析。

CMP 指令与 SUBS 指令的区别在于CMP 指令不保存运算结果。在进行两个数据大小判断时,常用CMP指令及相应的条件码来操作。B 指令用于跳转,其后跟的跳转条件如下:

  • BEQ Branch if EQual
  • BNE Branch if Not Equal
  • BVS Branch if oVerflow Set
  • BVC Branch if oVerflow Clear
  • BHI Branch if HIgher
  • BLS Branch if Lower or the Same
  • BPL Branch if PLus
  • BMI Branch if MInus
  • BCS Branch if Carry Set
  • BCC Branch if Carry Clear
  • BGE Branch if Greater than or Equal
  • BGT Branch if Greater Than
  • BLE Branch if Less than or Equal
  • BLT Branch if Less Than
  • BLEQ Branch with Link if EQual 
    ….
  • BLLT Branch with Link if Less Than

BCS表示如果 进位标志位 置位的话则跳转。如果寄存器 r5 中代表的无符号数据小于寄存器 r4 中代表的无符号数据的话,执行CMP指令之后,进位标志位置位,这里显然无符号数0xFFFFFFFF是大于0x01的。

BGE表示判断 r5 是否大于等于 r4,如果是,则跳转,这里就是有符号数的运算,虽然CMP指令的运算依然是一样的,但是对CMP指令的运算结果的看待方式改变了,以有符号数的运算来判断结果,因此0xFFFFFFFF其实被看成是 -1 ,所以 -1 < 1。 

参考文章:

https://blog.csdn.net/u014069939/article/details/81107340

https://blog.csdn.net/mickey35/article/details/82011449

 

猜你喜欢

转载自blog.csdn.net/tq384998430/article/details/103421002