c语言位运算问题解答:
要解答这个问题我们先来看一个例子,代码如下图一,图中右边是问题中得到代码,左边是这段代码的汇编指令。两种情况的不同点详细说明如下:
第一种情况:
printf("%d",2>>64);
由图中的汇编代码可以看出,如果两个数都是常数的情况下,代码中是不含对应的汇编指令的,因为编译器已经省略了,编译器算出结果为0,直接把0传入给printf函数。
第二种情况:
int i=2;
printf("%d",i>>64);
此时i是个变量,编译器没法在编译时算出结果,这时就需要通过SARL算术右移指令进行,这里考虑到溢出这个指令有一个调整机制,它会根据左操作数i类型来调整右操作数,比如这里i是4字节32位,也就是它最多右移32位,如果右操作数大于32它会进行64%32=0,所以i>>64相当于i>>0,如果是i>>63,63%32=31相当于i>>31。这种调整不同的编译器可能会不同,目前GCC是这样的。
所以这个代码在GCC环境下输出结果为:
0
2
补充说明:如果想要了解更多可以写出代码,然后观察编译出来的汇编代码。
gcc -S test.c
追问原来如此。那在编译过程中常量并不存在寄存器中吗?还有这段汇编代码有一点我不太明白,就是leaq .LC0(%rip), %rcx这段。这里的LC0是留做符号解析时候用的吗,而%rcx这个寄存器也是printf的参数之一?刚接触汇编,希望大佬指导一下
追答常量一般都会算好结果,用立即数进行操作。leaq是取得.lc0的地址,lc0存放的是常量字符串也就是代码里给printf的第一个字符串。函数参数,一般是第一个放在rcx, 第二个edx,整数是这样的,浮点数有专门的,具体你可以看下压栈的约定。
位运算是指按二进制进行的运算。在系统软件中,常常需要处理二进制位的问题。C语言提供了6个位操作
运算符。这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型。
C语言提供的位运算符列表:
运算符 含义 描述
& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
| 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1
^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1
~ 取反 ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0
<< 左移 用来将一个数的各二进制位全部左移N位,右补0
>> 右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0
1、“按位与”运算符(&)
按位与是指:参加运算的两个数据,按二进制位进行“与”运算。如果两个相应的二进制位都为1,
则该位的结果值为1;否则为0。这里的1可以理解为逻辑中的true,0可以理解为逻辑中的false。按位与其
实与逻辑上“与”的运算规则一致。逻辑上的“与”,要求运算数全真,结果才为真。若,
A=true,B=true,则A∩B=true 例如:3&5 3的二进制编码是11(2)。(为了区分十进制和其他进制,本文规
定,凡是非十进制的数据均在数据后面加上括号,括号中注明其进制,二进制则标记为2)内存储存数据
的基本单位是字节(Byte),一个字节由8个位(bit)所组成。位是用以描述电脑数据量的最小单位。
c语言位运算问题?
c语言位运算问题解答:要解答这个问题我们先来看一个例子,代码如下图一,图中右边是问题中得到代码,左边是这段代码的汇编指令。两种情况的不同点详细说明如下:第一种情况:printf("%d",2>>64);由图中的汇编代码可以看出,如果两个数都是常数的情况下,代码中是不含对应的汇编指令的,因为编译器...
c语言中,如何实现位运算?
c语言:取整型变量x中的第p位开始的n个bit位,可以采用位运算的方法。先向左移位,丢弃前面不需要的位,再通过向后移位,丢弃后面不需要的位,最后再向左移位到原来的位置,就可以了。1\/\/num&(num-1)=(1111)&(1110)=(1110)2\/\/num&(num-1)=(1110)&(1101)=(1100)3\/\/num&(num-1)=(11...
位运算~问题
1楼的回答是有问题的。在C语言里,整形常量可以有8进制,十进制,十六进制三种表示方式。十进制与正常的表述类似,如a=111; 那就是说a的值是111;而八进制整数常量的表示,以数字前面加0表示,也就是a=0111,则表示是八进制的111,111(八)=1*8*8+1*8+1=73(十)而十六进制整数常量的表示...
c语言的位运算疑惑
2:ASCII编码表中 32表示的是空格符号。 char中寸的是ASCII编码,所以是32 3:位移运算:>>表示右移位 我以8为例。8的二进制是1000, 8>>1对应的二进制形式就是1000——0100看到变化了没有。所以右移位相当于这个数除2 左移位你看看 01000——10000是16了。相当扩大一倍。32的二进制是 0010...
C语言位运算取反问题?
首先你输出是肯定用的 printf("%d",~a).int类型数据是有范围的 -32768~32767 [100]原=0000 0000 0110 0100 取反后为1111 1111 1001 1011 这个数值已远远超出了范围,发生溢出.但是这个数值是-101的补码,而计算机数字都是按补码存储的,所以他输出了-101.你放成ld,数值又不同....
C语言中位运算符问题 这句话怎么解释啊
就不等于8除以8了;根据以上分析,对于带符号数负数,发现右移时有两种情况:补1(也就是符号位)进来,还能够保持除以2的n次方的关系成立;补0进来就不行。不同的C编译系统根据自己的特点在这个问题上可能就采取了不同的办法。比如VC和DEV C++,对于带符号数的右移运算就采取了补符号位的方式。
C语言问题,在位运算中,操作数每右移一位,其结果相当于什么?若左移1位...
1、右移,除以2右移n位除以2的n次方;右移的概念和左移相反,就是往右边挪动若干位,运算符是>>;右移对符号位的处理和左移不同,对于有符号整数来说,比如int类型,右移会保持符号位不变,例如:inti=0x80000000;i=i>>1;\/\/i的值不会变成0x40000000,而会变成0xc0000000 2、左移,乘以2...
C语言——位运算
本文将介绍C语言中的位运算,它允许程序员直接操作二进制位。二进制位,或“位”,仅包含0或1。在计算机中,数据以二进制形式表示,执行的指令亦是如此。计算机内部的数据以补码形式存储。这意味着,对于数字的二进制表示,最左侧的位(符号位)指示数字是正还是负。位运算包括:取反运算、左移运算、...
C语言位运算题目
一、位运算符c语言提供了六种位运算符:&按位与 |按位或 ^按位异或 ~取反 <<左移 >>右移 1.按位与运算按位与运算符"&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1,否则为0。参与运算的数以补码方式出现。例如:9&5可写算式...
0基础学习C语言第三章:位运算
在C语言的学习过程中,位运算是一种非常重要的操作。它提供了六种基本位运算符,分别是:按位与(&)、按位或(|)、按位异或(^)、取反(~)、左移(<<)和右移(>>)。下面,我们将深入探讨这些运算符的原理和应用。首先,我们来看按位与运算。按位与运算符"&"用于参与运算的两个数的对应二进位...