asm - 汇编cmp指令
本文介绍了asm - 汇编cmp指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问 题
code小白。。
代码在这里,64位编译环境。还是刚才那个阶乘。
#include<stdio.h>
int fac(int n);
int main(){
int num;
scanf("%d", &num);
while( num < 0) {
scanf("%d",&num);
}
printf("%d", fac(num));
return 0;
}
int fac(unsigned n){
int f;
if (n == 0) {
f = 1;
} else{
f = fac(n-1) * n;
}
return f;
}
https://github.com/SarishiNoH...
问题是在这段比较num和0的大小的时候
scanf("%d", &num);
while( num < 0) {
scanf("%d",&num);
}
想请教一下为什么在.compare这段中如果我把37行写成
cmpq $0, %rax
之后我每次输入负数的时候就会出现segment fault,
而%eax就可以正常运行,为啥?
rax和eax里面如果都是负数的话有什么区别吗?
解决方案
首先,RAX
是64位的寄存器,EAX
是32位的寄存器,他们的关系如下(别处copy来的):
|63..32|31..16|15-8|7-0|
|AH. |AL.|
|AX......|
|EAX............|
|RAX...................|
或者用16进制这么看
0x1122334455667788
================ RAX (64 bits)
======== EAX (32 bits)
==== AX (16 bits)
== AH ( 8 bits)
== AL ( 8 bits)
然而,C语言中int
是32bit,当你的数是正数的时候,RAX
高位都是0
,无影响,比如数字2000
,即使是64位寄存器,存的也是2000
EAX 0000 0000 0000 0000 0000 0111 1101 0000
RAX 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111 1101 0000
但是,如果是负数,是采用补码的形式存储,那么首个二进制位必须是1
,比如数字-5
首先看一下是怎么存储的
1000 0000 0000 0000 0000 0000 0000 0101
^ ^^^
符号位为1 十进制5
符号位以外的取反
1111 1111 1111 1111 1111 1111 1111 1010
^
符号位不变
1111 1111 1111 1111 1111 1111 1111 1011
^
然后加1
所以最终-5
在EAX
中是,但是如果你用RAX
的话,高位都是0
,那是正数啊!
EAX 1111 1111 1111 1111 1111 1111 1111 1011
RAX 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 1111 1011
如果用了RAX
,这个是就不是-5
而是4294967291
了~
不知道我算的对不对... 总之你用int
的话,肯定是用EAX
的啦。
这篇关于asm - 汇编cmp指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文