社区
C语言
帖子详情
怎样用C实现逻辑右移、和算术左移?
cnss
2001-10-01 09:51:17
如题
...全文
2695
15
打赏
收藏
怎样用C实现逻辑右移、和算术左移?
如题
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
15 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
std::coding::peasant
2001-10-04
打赏
举报
回复
老兄,我学习汇编语言时老师讲,我又翻了课本证实:
SAL 指令同 SHL,是同一条指令的两种助记符,他们执行的操作完全相同。
SAR 与 SHR 不同,SHR 连符号一起右移,左边高位补0,而 SAR 空位补的不是0,而是原来的符号位。
我用汇编语言编了一个小程序证实:
cseg segment byte
assume cs:cseg,ds:cseg,ss:cseg
org 100h
main proc near
shl ax,cl
sal ax,cl
shr ax,cl
sar ax,cl
ret
main endp
cseg ends
end main
编译结果:
t:\>debug 1.COM
-u
10F6:0100 D3E0 SHL AX,CL
10F6:0102 D3E0 SHL AX,CL
10F6:0104 D3E8 SHR AX,CL
10F6:0106 D3F8 SAR AX,CL
10F6:0108 C3 RET
10F6:0109 C54C8B LDS CX,[SI-75]
10F6:010C CAE307 RETF 07E3
10F6:010F B020 MOV AL,20
10F6:0111 50 PUSH AX
10F6:0112 51 PUSH CX
10F6:0113 E83400 CALL 014A
10F6:0116 833E6C4C00 CMP WORD PTR [4C6C],+00
10F6:011B 751B JNZ 0138
10F6:011D FF066C4C INC WORD PTR [4C6C]
-q
t:\>
void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
asm sal eax,cl
asm shl eax,cl
asm sar eax,cl
asm shr eax,cl
}
在 DEBUG 运行时:
0040193C 55 push ebp
0040193D 8BEC mov ebp,esp
0040193F 83C4F8 add esp,-0x08
00401942 8955F8 mov [ebp-0x08],edx
00401945 8945FC mov [ebp-0x04],eax
00401948 D3E0 shl eax,cl
0040194A D3E0 shl eax,cl
0040194C D3F8 sar eax,cl
0040194E D3E8 shr eax,cl
00401950 59 pop ecx
00401951 59 pop ecx
00401952 5D pop ebp
00401953 C3 ret
SAL 和 SHL 完全一样
看来C语言的算术移位和逻辑移位和汇编语言是一样的,根本没有必要用汇编语言去编
cnss
2001-10-04
打赏
举报
回复
http://www.csdn.net/expert/TopicView.asp?id=311853
到这里来
cnss
2001-10-04
打赏
举报
回复
to ybchen
谢谢了,确实能行
我用汇编做了逻辑右移和算术左移,现在把逻辑右改用C
我要的是真正的算术左移,看来只能是汇编了
std::coding::peasant
2001-10-04
打赏
举报
回复
cnss()老兄试过了没有?
std::coding::peasant
2001-10-02
打赏
举报
回复
逻辑移位:(unsigned)>> 和 (unsigned)<<
算术移位:(signed)>> 和 (signed)<<
int main(void)
{
int x = 0xabcd;
unsigned int y = 0xdcba;
x<<=2; //与 (signed int)x<<=2; 相同,因为变量本身是signed
(unsigned int)x<<=2;
x>>=2;
(unsigned int)x>>=2;
(signed int)y<<=2;
y<<=2;
(signed int)y>>=2;
y>>=2;
return x+y;
}
汇编结果:
_TEXT segment byte public 'CODE'
assume cs:_TEXT,ds:DGROUP
_main proc near
?debug C E80105312E63707012AD422B
;
; int main(void)
;
push bp
mov bp,sp
;
; {
; int x = 0xabcd;
;
mov dx,-21555
;
; unsigned int y = 0xdcba;
;
mov bx,-9030
;
;
; x<<=2;
;
shl dx,2
;
; (unsigned int)x<<=2;
;
shl dx,2
;
; x>>=2;
;
sar dx,2
;
; (unsigned int)x>>=2;
;
shr dx,2
;
;
; (signed)y<<=2;
;
shl bx,2
;
; y<<=2;
;
shl bx,2
;
; (signed)y>>=2;
;
sar bx,2
;
; y>>=2;
;
shr bx,2
;
;
; return x+y;
;
mov ax,dx
add ax,bx
;
; }
;
pop bp
ret
_main endp
?debug C E9
?debug C FA00000000
_TEXT ends
因为算术左移和逻辑左移的结果一样,所以都编译成逻辑的,而右移不同,编译结果也不同
cnss
2001-10-02
打赏
举报
回复
to ybchen(),我试了,确实是cui说的那样
; 15 : shl eax, cl
00022 d3 e0 shl eax, cl
; 16 : sal eax, cl
00024 d3 e0 shl eax, cl
00022,00024是编译以后的,都一样
std::coding::peasant
2001-10-02
打赏
举报
回复
楼上的回答完全错误!
C语言是分逻辑移位和算术移位的!当然有逻辑右移、和算术左移啦!
蚊子王
2001-10-01
打赏
举报
回复
>>我想知道怎样用C实现逻辑右移
还是内嵌ASM吧
蚊子王
2001-10-01
打赏
举报
回复
逻辑左移和算术左移事实上是一样的;逻辑右移C/C++中没有,JAVA里倒有一个(>>>)
vince_xu
2001-10-01
打赏
举报
回复
何谓逻辑左移?是不是循环左移?
cnss
2001-10-01
打赏
举报
回复
通过观看VC6生成的汇编代码:
GR[GRI] = GR[GRI] << ADR; //这是逻辑左移
GR[GRI] = GR[GRI] >> ADR; //这里却是算术右移
我觉得在一个编译系统里应该是一致的,但VC6好象不是样
所以,我想知道怎样用C实现逻辑右移和算术左移
gigix
2001-10-01
打赏
举报
回复
C语言的移位操作似乎不区分逻辑和算术的。JAVA有区分。
cnss
2001-10-01
打赏
举报
回复
哦,原来是这样啊
谢谢你
蚊子王
2001-10-01
打赏
举报
回复
to cnss():逻辑左移和算术左移事实上是一样(一个机器代码,两种表示),不信看看生成的机器代码?
cnss
2001-10-01
打赏
举报
回复
to cui:
逻辑左移是全都移,算术左移不移符号位
想了想,我还是内嵌ASM吧
谢谢大家!
c语言
左移
和
右移
的示例详解
逻辑
移位,简单理解就是物理上按位进行的左
右移
动,两头用0进行补充,不关心数值的符号问题。
算术
移位,同样也是物理上按位进行的左
右移
动,两头用0进行补充,但必须确保符号位不改变。
算术
移位指令
算术
移位指令有:
算术
左移
SAL(ShiftAlgebraic Left)和
算术
右移
SAR(ShiftAlgebraic Right)。
算术
移位指令的功能描述如下: (1)
算术
左移
SAL把目的操作数的低位向高位移,空出的低位补0; (2)
算术
右移
SAR把目的操作数的高位向低位移,空出的高位用最高位(符号位)填补。
逻辑
移位指令 此组指令有:
逻辑
左移
SHL(ShiftLogical Left)和
逻辑
右移
SHR
C语言的移位操作
关于C语言位操作,
左移
时总是移位和补零。
右移
时无符号数是移位和补零,此时称为
逻辑
右移
;而有符号数大多数情况下是移位和补最左边的位(也就是补最高有效位),移几位就补几位,此时称为
算术
右移
。
ALU1.rar_VHDL/FPGA/Verilog_VHDL_
ALU 指令格式(16位) op DR SR fun 0--3 4—7 8--11 12--15 指令类 OP码 指令 FUN 功能描述控制 0000 NOP 0000 空指令 HLT 0001 停机有条件跳转 0010 JZ 0000 Z=1,跳转 JC 0001 C=1,跳转 JNC 0010 C=0,跳转 JNZ 0100 Z=0,跳转 Jump 0101 无条件跳转LOAD 0011 [SR]->DRSTORE 0100 SR->[DR]MOV(reg to reg) 0101 SR->DRMOV(IMM to reg) 0110 IMM->DR移位 0111 SHL 0000
逻辑
左移
/
算术
左移
SHR 0001
逻辑
右移
SAR 0010
算术
右移
RCL 0011 含进位的左循环移位 RCR 0100 含进位的右循环移位 ROL 0101 不含进位左循环移位 ROR 0111 不含进位右循环移位
算术
类 1000 ADD 0000 DR+SR->DR SUB 0001
计算机二级c语言资料.zip
计算机二级c语言资料 一、C语言基础知识 数据类型 基本数据类型:整型(int)、浮点型(float, double)、字符型(char) 构造数据类型:数组、结构体(struct)、联合体(union)、枚举(enum) 指针类型:指向各种数据类型的指针 空类型(void) 运算符与表达式
算术
运算符:加(+)、减(-)、乘(*)、除(/)、取模(%) 关系运算符:大于(>)、小于(<)、等于(==)、不等于(!=)、大于等于(>=)、小于等于(<=)
逻辑
运算符:
逻辑
与(&&)、
逻辑
或(||)、
逻辑
非(!) 位运算符:按位与(&)、按位或(|)、按位异或(^)、按位取反(~)、
左移
(<<)、
右移
(>>) 赋值运算符:赋值(=)、复合赋值(如 +=、-=) 条件运算符(?:) 逗号运算符(,) 指针运算符(&、*) 长度运算符(sizeof)
详解C++编程中运算符的使用
C++的运算符十分丰富,使得C++的运算十分灵活方便。例如把赋值号(=)也作为运算符处理,这样,a=b=c=4就是合法的表达式,这是与其他语言不同的。C++提供了以下运算符:
算术
运算符 +(加) -(减) *(乘) /(除) %(整除求余) ++(自加) –(自减) 关系运算符 >(大于) <(小于) ==(等于) >=(大于或等于) <=(小于或等于) !=(不等于)
逻辑
运算符 &&(
逻辑
与) ||(
逻辑
或) !(
逻辑
非) 位运算符 <<(按位
左移
) >>(按位
右移
) &(按位与) |(按位或) ^(按位异或) ~(按位取反) 赋值运算符 (=及
C语言
69,369
社区成员
243,082
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章