unsigned int无符号和int有符号的加法,乘法和取反

本文深入探讨了C语言中无符号与有符号整数的加、减、乘、取反运算,通过对比分析及代码示例,揭示了它们在底层实现上的异同,特别是汇编指令的使用及其对标志位的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

无符号和有符号

在C语言里,整数的表示有有符号无符号两种

无符号有符号32位64位
unsigned charchar11
unsigned shortshort22
unsigned intint44
unsigned longlong48
unsigned long longlong long88

无符号是用原码表示,有符号使用补码表示,那么他们的加,减,乘,积,取反是否有区别呢?

测试代码

#include <stdio.h>
int main()
{
	int a = 10 , b= 10;
	unsigned c = 10, d= 10;
	a = a+b;
	c = c+d;
}

在这里插入图片描述
无符号加法和有符号加法都是使用使用 add指令,我感觉应该很清晰

#include <stdio.h>
int main()
{
	int a = 10 , b= 10;
	unsigned c = 10, d= 10;
	a = a-b;
	c = c-d;
}

在这里插入图片描述

无符号加法和有符号减法都是使用使用 sub指令,我感觉也应该很清晰,毕竟补码的作用就是把原来减法运算统一成加法运算,所以本质上sub指令和add指令是一样的

测试代码:

#include <stdio.h>
int main()
{
	int a = 10,b = 10;
	unsigned c = 10,d = 10;
	a *=b;
	c*=d;
}

在这里插入图片描述

通过反汇编之后,发现无论是有符号int,还是无符号unsigned int,使用的都是无符号乘法指令imul。
所以无符号乘法和有符号乘法都是一样的(后面证明)
那为什么指令集系统里要用imul(无符号乘法)和mul(有符号乘法)呢?
经过Google发现:imul和mul的确是一样的,唯一的区别是执行完后对标志位flags中CF和OF设置。但是标志位是我们不care的。
实在想知道的:可以看下边ORACLE 提供的IA-32 汇编语言参考手册中imul和mul对标志位flags的影响
ORACLE imul指令
ORACLE mul指令

取反

#include <stdio.h>
int main()
{
	int a = 10;
	unsigned c = 10;
	a = -a;
	c = -c;
}

在这里插入图片描述
可能会有质疑:无符号求反,好像是UB,的确,无符号求反在GCC上可以通过编译,但是在visual studio上报错。但是本文是对于csapp里的总结,所以就当学知识了。

ref
CSAPP

ORACLE imul
ORACLE mul
x86汇编当中imull 和 mull 区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值