汇编中的有符号-无符号-溢出-进位

什么是有符号数?什么是无符号数?什么是溢出(OF)?什么是进位(CF)?如何区分有无符号 呢?
有符号数,就是带符号的数,可以是正数或负数。区分正数或负数时,看这个数的最高位是 否为 1,最高位为 1,说明它是负数。最高为 0 说明它是正数。
例如
一个字节有符号数,表示范围(-128 ~ 127):
A0 :1010 0000 : -96 最高位为 1,说明是负数 80 :1000 0000 :-128 最高位为 1,说明是负数 5B :0101 1011 : 91 最高位位 0,说明它是正数 09 :0000 1001 : 9 最高位位 0,说明它是正数
两个字节有符号数,表示范围(-32768 ~ 32767):
A055: 1010 0000 0101 0101 :-24491 201A: 0010 0000 0001 1010 :8218 35B9: 0011 0101 1011 1001 :13753
最高位为 1,说明是负数 最高为 0,说明它是正数 最高为 0,说明它是正数
现在我们对于有符号数有了了解,那么无符号数呢? 无符号说明这个数是没有符号的,那么它的最高位将会变成有效位。不会再用来检查是否正 负数。
一个字节无符号数,表示范围(0~ 256): A0:1010 0000 :160
BE:1011 1110 :190
90:1001 0000 :144
50:0101 0000 :80
两个字节无符号数,表示范围(0~ 65536): EA00: 1110 1010 0000 0000 : 59904 8000: 1000 0000 0000 0000 : 32768 0900: 0000 1001 0000 0000 : 2304
0080: 0000 0000 1000 0000 :128
可以发现无符号数就是正数,没有负数,范围就非常的大。
现在了解了有符号和无符号数,接下来继续理解什么是溢出!
溢出:当有符号位超出它的表示范围就算溢出。
用个例子来表示(1 个字节加法):
0x80 + 0x9F = 0x(1)1F 最终结果等于 0x1F(31)
上面的例子非常明显,十六进制0x80是十进制-128, 十六进制0x90是十进制-112 那么他们 相加结果是应该-240,-240 已经超过 1 个字节有符号数(-128~127)的表示范围了,结果明

显是错误的。此时我们就可这两个数相加就算溢出。 再用一例子来表示(1 个字节减法):
0x80 – 0x46 = 0x3A 结果等于 0x3A(58)
明显结果是错误的,十六进制 0x80 是十进制-128,十六进制 0x46 是十进制 70, (-128 )– ( 70 )= -198 结果应该是一个负数,而且这个数明显已经超过 1 个字节有符号数(-128~127) 的表示范围了,这也是溢出。
现在大致明白了什么是溢出,总结一下有这种规律:
当两个有符号数进行运算时,符号位不同时,相加或相减不可能溢出。
只有在符号位相同情况,进行运算下才会溢出。
什么是进位? 对于进位来说,在无符号进行运算时才会产生进位(加法)或者借位(减法)。
举个例子(1 个字节):
0xEA +0x55 = 0x(1)3F 结果大于无符号(0-256)所能容纳的范围,产生进位(CF=1)。 0x10 – 0x14= 0xFC 结果由于被减数小于减数,此时就会产生借位(CF=1)
到此我们应该能理解什么是溢出?什么是进位(借位)?
但是可能会有人问,那我在汇编中计算一个值,我怎么知道它是有符号,还是无符号,有该 怎么去区分呢?
答案是:没有区分,或者说你当它有符号可以,无符号也可以。 在看一个例子:
0x80 + 0x8F = 0x(1)0F
这个例子中相加后结果即产生了进位,又产生了溢出。
CF =1 ,OF =1;
所以 CPU 不区分有符号或者无符号,它在计算时都当成有符号进行计算,根据结果设置标 志位。
区分有符号,或无符号是汇编指令。或者说是你决定的。
C 中有 unsigned 与 signed 来确定有无符号。
汇编中有写指令区分有无符号。

原文地址:http://blog.51cto.com/haidragon/2097432

时间: 2024-10-14 04:13:48

汇编中的有符号-无符号-溢出-进位的相关文章

INT_MIN 写成 (-2147483647 - 1) 和 vs中 warning C4018: “>”: 有符号/无符号不匹配的深入剖析。

首先明确下4个字节的INT能表示的数字范围是2147483647-- -2147483648,来看我遇到的问题: 这里输出了"相等"说明 (INT_MIN==-2147483648) 为true. 输出了" 1<-2147483648",说明认为 (1<-2147483648) 为true,但是这不科学. 输出了"-1>2147483648"说明 ( -1>2147483648) 为true,这也不科学. INT_MIN和

C语言 宏判断有符号无符号 整型变量

#define ISUNSIGNED(x) ((x)>=0&&~(x)>=0) #define ISSINGNED(x) ((x)>=0?((~(x))<0?true:false):true) 有符号与无符号的区别:最高位是否为1  ,有符号最高位为1表示负数.

警告:C4018 &quot;&lt;&quot;:有符号/无符号不匹配

for (i = 0; i<(strlen(arr1)+1)/2; i++) 只需将循环中的"i"在定义时定义为无符号即可,即unsigned i; 产生错误的代码: #include<stdio.h> #include<stdlib.h> #include<string.h> int main() {  char arr1[] = { "Welcome to bit!" };  int num = strlen(arr1)

【VHDL】深度讲解无符号和有符号加法处理溢出的问题

1.Unsigned adders 这个比较简单,只需在A.B前面扩展一位0防止溢出,溢出的数填到第n位cout,n-1到0位就是sum. , 2.Signed adders 一开始也搞不懂下图中为什么要扩展符号位,两个符号位了怎么加?   往下看↓ 2.1 Analysis 在真正开始使用Verilog做signed加法运算前,我们先来看看实际上二进制singed加法是如何运算? Normal Condition (没有Overflow) (+6) + (-3) = (+3) 为了节省reso

有符号数、无符号树混合计算问题。

今天在线刷题,其中一个问题总是结果跟期望的不一样,在一次次的检查程序逻辑.确认无误后,还是不能通过,不得已用VS开始调试! 这里是我的程序代码: 1 // maxDepth.cpp : 定义控制台应用程序的入口点. 2 // 3 4 #include "stdafx.h" 5 #include<vector> 6 #include<iostream> 7 #include<limits.h> 8 9 using namespace std; 10 1

C语言 有符号、无符号

C语言 有符号.无符号 有符号无符号说明 一.有符号 signed char 8bit 取值范围:-2^7 ~ 2^7-1 . -128~127 int 32bit 取值范围:-2^31 ~ 2^31-1 . -2147483648~2147483647 long long 64bit 取值范围:-2^63 ~ 2^63-1 #include <stdio.h> int main() { signed int a = -1089474374; //定义有符号整型变量a printf("

汇编总结:无符号除法,有符号除法,取余,无符号乘法,有符号乘法

本文分为3个模块. 示例---该指令的示例 解释---为指令不好理解的地方 练习---为了更熟悉该指令 1.1 有符号除法指令及取余example: 在c语言里要完成 8 / 2的汇编指令如下: 在c语言里要完成 8 % 2的汇编指令如下: 4个字节的除法及取余运算示例如下: .section .text .global _start _start:     movl $8, %eax   #被除数是%edx:%eax 是这两个寄存器拼起来的%eax存放低位%edx存储高位     movl %

【 c语言中无符号和有符号的加法运算】【深入理解】--【sky原创】

原文:[ c语言中无符号和有符号的加法运算][深入理解]--[sky原创] 第一题 #include<stdio.h> int main() { unsigned int a=6; int b=-20; printf("%d\n",a+b); (a+b)>6? puts(">6"):puts("<=6"); return 0; } 答案是:>6 第二题 #include<stdio.h> int m

c语言中无符号和有符号之间的运算

关于计算机中有符号,无符号数值的表示以及它们之间的运算 是基本知识,但工作这么多年也不敢说完全搞明白透彻. 这几天在将知识点进行了一些梳理,并做了一些有意思的试验. 计算机中,数值的表示和运算都是用补码表示的. 正数的补码就是其本身: 负数的补码则是最高符号位为1,其余位取反加1. 比如-5表示为0xFFFB, 而5则表示为0x0005. 这里,第一个需要注意的问题就是 有符号数和无符号数之间的运算. c语言规定,先一律转成无符号数,然后再进行运算. 比如,  int iValue1 = -5;