汇编中有符号与无符号数的区分

2023-10-27

origin: http://blog.chinaunix.net/uid-28458801-id-3576608.html
转载自:http://hi.baidu.com/asmsky/blog/item/7290d20076cab6da277fb5b8.html
一、只有一个标准!


在汇编语言层面,声明变量的时候,没有 signed   和   unsignde 之分,汇编器统统,将你输入的整数字面量当作有符号数处理成补码存入到计算机中,只有这一个标准!汇编器不会区分有符号还是无符号然后用两个标准来处理,它统统当作有符号的!并且统统汇编成补码!也就是说,db -20 汇编后为:EC ,而 db 236 汇编后也为 EC 。这里有一个小问题,思考深入的朋友会发现,db 是分配一个字节,那么一个字节能表示的有符号整数范围是:-128 ~ +127 ,那么 db 236 超过了这一范围,怎么可以?是的,+236 的补码的确超出了一个字节的表示范围,那么拿两个字节(当然更多的字节更好了)是可以装下的,应为:00 EC,也就是说 +236的补码应该是00 EC,一个字节装不下,但是,别忘了“截断”这个概念,就是说最后的结果被截断了,00 EC 是两个字节,被截断成 EC ,所以,这是个“美丽的错误”,为什么这么说?因为,当你把 236 当作无符号数时,它汇编后的结果正好也是 EC ,这下皆大欢喜了,虽然汇编器只用一个标准来处理,但是借用了“截断”这个美丽的错误后,得到的结果是符合两个标准的!也就是说,给你一个字节,你想输入有符号的数,比如 -20 那么汇编后的结果是正确的;如果你输入 236 那么你肯定当作无符号数来处理了(因为236不在一个字节能表示的有符号数的范围内啊),得到的结果也是正确的。于是给大家一个错觉:汇编器有两套标准,会区分有符号和无符号,然后分别汇编。其实,你们被骗了。:-)


二、存在两套指令!


第一点说明汇编器只用一个方法把整数字面量汇编成真正的机器数。但并不是说计算机不区分有符号数和无符号数,相反,计算机对有符号和无符号数区分的十分清晰,因为计算机进行某些同样功能的处理时有两套指令作为后备,这就是分别为有符号和无符号数准备的。但是,这里要强调一点,一个数到底是有符号数还是无符号数,计算机并不知道,这是由你来决定的,当你认为你要处理的数是有符号的,那么你就用那一套处理有符号数的指令,当你认为你要处理的数是无符号的,那就用处理无符号数的那一套指令。加减法只有一套指令,因为这一套指令同时适用于有符号和无符号。下面这些指令:mul div movzx … 是处理无符号数的,而这些:imul idiv movsx … 是处理有符号的。
举例来说:
内存里有 一个字节x 为:0x EC ,一个字节 y 为:0x 02 。当把x,y当作有符号数来看时,x = -20 ,y = +2 。当作无符号数看时,x = 236 ,y = 2 。下面进行加运算,用 add 指令,得到的结果为:0x EE ,那么这个 0x EE 当作有符号数就是:-18 ,无符号数就是 238 。所以,add 一个指令可以适用有符号和无符号两种情况。(呵呵,其实为什么要补码啊,就是为了这个呗,:-))
乘法运算就不行了,必须用两套指令,有符号的情况下用imul 得到的结果是:0x FF D8 就是 -40 。无符号的情况下用 mul ,得到:0x 01 D8 就是 472 。(参看文后附录2例程)


三、可爱又可怕的c语言。


为什么又扯到 c 了?因为大多数遇到有符号还是无符号问题的朋友,都是c里面的 signed 和 unsigned 声明引起的,那为什么开头是从汇编讲起呢?因为我们现在用的c编译器,无论gcc 也好,vc6 的cl 也好,都是将c语言代码编译成汇编语言代码,然后再用汇编器汇编成机器码的。搞清楚了汇编,就相当于从根本上明白了c,而且,用机器的思维去考虑问题,必须用汇编。(我一般遇到什么奇怪的c语言的问题都是把它编译成汇编来看。)


C 是可爱的,因为c符合kiss 原则,对机器的抽象程度刚刚好,让我们即提高了思维层面(比汇编的机器层面人性化多了),又不至于离机器太远 (像c# ,java之类就太远了)。当初K&R 版的c就是高级一点的汇编……:-)


C又是可怕的,因为它把机器层面的所有的东西都反应了出来,像这个有没有符号的问题就是一例(java就不存在这个问题,因为它被设计成所有的整数都是有符号的)。为了说明c的可怕特举一例:


#include <stdio.h>
#include <string.h>


int main()
{
int x = 2;
char * str = "abcd";
int y = (x - strlen(str) ) / 2;


printf("%d\n",y);
}


结果应该是 -1 但是却得到:2147483647 。为什么?因为strlen的返回值,类型是size_t,也就是unsigned int ,与 int 混合计算时类型被自动转换了,结果自然出乎意料。。。
观察编译后的代码,除法指令为 div ,意味无符号除法。
解决办法就是强制转换,变成 int y = (int)(x - strlen(str) ) / 2; 强制向有符号方向转换(编译器默认正好相反),这样一来,除法指令编译成 idiv 了。我们知道,就是同样状态的两个内存单位,用有符号处理指令 imul ,idiv 等得到的结果,与用 无符号处理指令mul,div等得到的结果,是截然不同的!所以牵扯到有符号无符号计算的问题,特别是存在讨厌的自动转换时,要倍加小心!(这里自动转换时,无论gcc还是cl都不提示!!!)




为了避免这些错误,建议,凡是在运算的时候,确保你的变量都是 signed 的。(完)






附录
1:IA-32 Intel Architecture Software Developer’s Manual》第2卷PDF文档表述为“sign-extended imm8”,这个sign-extended 是符号扩展的意思。说说符号扩展:当操作数进行长度扩展时,既要让操作数变长又不能改变原数值,所以就出现了符号扩展一说。比如 movsx ax, 0xEC   ,执行扩展后,ax的值为:0xFFEC,长度变长了,结果没变,都是 -20 。


2:两套乘法指令结果例程


;; 程序存储为 x.s
;;--start--------------------------------------------------------


extern printf
global main


section .data
str1: db "%x",0x0d,0x0a,0
n: db 0x02
section .text
main:
xor eax,eax
mov al, 0xec
mul   byte [n]   ;有符号乘法指令为: imul


push eax
push str1
call printf


add esp,byte 4
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

汇编中有符号与无符号数的区分 的相关文章

  • 编译原理书籍推荐

    大学课程为什么要开设编译原理呢 这门课程关注的是编译器方面的产生原理和技术问题 似乎和计算机的基础领域不沾边 可是编译原理却一直作为大学本科的必修课程 同时也成为了研究生入学考试的必考内容 编译原理及技术从本质上来讲就是一个算法问题而已 当
  • 【编译原理】SLR(1)分析方法(c++实现)

    基本流程 Created with Rapha l 2 2 0 输入文法 拓广文法 构造DFA 识别活前缀的自动机 SLR 1 分析表 SLR 1 分析输入串
  • 编译原理笔记

    目录 序章 编译原理 编译器 程序设计语言 第一章 概述 机器语言 第一代语言 特点 汇编语言 高级程序设计语言 鼻祖 时期 特点 翻译程序 汇编语言 解释语言 编译程序 编译过程 词法分析 语法分析 语义分析 中间代码生成 之前三步都是编
  • 编译原理 实验一 词法分析器设计

    一 实验目的 1 深入理解有限自动机及其应用 2 掌握根据语言的词法规则构造识别其单词的有限自动机的方法 3 基本掌握词法分析程序的开发方法 4 能够设计词法扫描器程序 对源程序进行词法分析 并输出单词序列 二 实验内容及要求 编写识别单词
  • 编译原理实验 实验二 LL(1)分析法 Python实现

    1 实验目的 通过完成预测分析法的语法分析程序 了解预测分析法和递归子程序法的区别和联系 使学生了解语法分析的功能 掌握语法分析程序设计的原理和构造方法 训练学生掌握开发应用程序的基本方法 有利于提高学生的专业素质 为培养适应社会多方面需要
  • 【编译原理】【C语言】实验三:递归下降分析法

    C语言 实验环境 Visual Studio 2019 author zoxiii 递归下降分析法 1 实验内容 2 前期准备 2 1 递归下降分析法原理 2 2 要实现的文法 2 3 需要的函数 3 分析过程 3 1 递归下降分析法设计思
  • 【编译原理】- 递归下降的语法分析器的实现

    目录 一 实验题目 二 分析与设计 三 源代码 一 实验题目 编写识别由下列文法G E 所定义的表达式的递归下降语法分析器 E E T E T T T T F T F F F E i 输入 含有十进制数或十六进制数的表达式 如 75 1ah
  • 编译原理------语法分析器C/C++代码实现

    一 实验目的 编制一个递归下降分析程序 实现对词法分析程序所提供的单词序列的语法检查和结构分析 二 实验内容 利用C语言编制递归下降分析程序 并对简单语言进行语法分析 2 1 待分析的简单语言的语法 用扩充的BNF表示如下 lt 程序 gt
  • 静态类型推导

    前面说泛型的时候 提到了C 模板的实现方式是动态特性静态化 在实际情况中 这是一个提高效率的好办法 动态性的好处是灵活 开发简便 静态性的特性是效率高 编译期检查较好 因此很自然地就有一个问题 能不能各取所长 达到两全其美 应该说 在一定程
  • 初识 flex & bison

    基本概念 flex 和 bison 经常结合使用 分别用于词法分析和语法分析 词法分析器 flex flex 用于生成词法分析器或者说是扫描器 scanner 它将输入的文本分解为称为 tokens 的序列 每个 token 都有一个特定的
  • 语义分析- C-- 语言

    C V1 0 E gt n true false E E E E 类型合法的程序 3 4 false true 类型不合法的程序 3 true true false 对这个语言 语义分析的任务是 对给定的一个表达式e 写一个函数type c
  • 简单的递归下降语法分析程序

    简单递归分析程序 其代码如下 include
  • 编译原理 实验四 LR(1)分析法程序

    源代码仓库 CompilePrincipleLearning experiment 4 yusixian CompilePrincipleLearning github com 源代码在demo文件夹中 一 实验目的 掌握LR 1 分析法的
  • 编译原理 CS-143(更新至week4)

    编译原理 CS 143 Pre Course Survey Navigation Your Course 01 01 Introduction 8m20s 01 02 Structure of a Compiler 13m53s 编译器结构
  • 编译原理实验二:Bison

    编译原理实验二 Bison 实验要求 1 了解Bision基础知识 如何将文法产生式转换为Bison语句 2 阅读 src common SyntaxTree c 对应头文件 include SyntaxTree h 理解分析树生成的过程
  • 程序语言翻译器的设计与实现----算术表达式转换四元式(编译原理)

    此篇博客是将前面的内容进行整合并进一步提升 真正实现一个简单表达式语法的编译器 如果有不了解的地方请查看下面链接 词法分析 LR 1 分析 一 LR 1 分析 二 这里说的程序语言编译器是指将算术表达式部分进行翻译 暂时不包括优化以及目标语
  • 【Python】代码实现LL(1),LR(1)上下文无关文法(Stack()类)

    任务要求 针对书上第三章中的表达式文法 采用LL 1 LR 1 进行分析 相关文法 需要进行消除左递归等操作 顺手分享一下课本资源好了 可能不是最新版 排版略有点别扭 后文的书上内容就是指这本书 编译原理 陈意云 文字版 提取码 e0ag
  • QT210烧写UBOOT到SD卡原理以及UBOOT启动

    原文地址 http blog csdn net shushi0123 article details 8018998 世界早已进入cortex a8了 我也得跟进一下所以买了QT210的开发板 长话短说开始搞SD卡烧写UBOOT 从SD启动
  • 语义分析- 符号表

    符号表 1 用来存储程序中的变量相关信息 类型 作用域 访问控制信息 2 必须非常高效 程序中的变量规模会很大 符号表的接口 ifndef TABLE H define TABLE H typedef Table t 数据结构 新建一个符号
  • Go 程序编译过程(基于 Go1.21)

    版本说明 Go 1 21 官方文档 Go 语言官方文档详细阐述了 Go 语言编译器的具体执行过程 Go1 21 版本可以看这个 https github com golang go tree release branch go1 21 sr

随机推荐

  • 【机器学习实战】9、利用K-means算法对未标注数据分组

    文章目录 10 1 K 均值聚类算法 10 2 使用后处理来提高聚类性能 10 3 二分K 均值算法 10 4 总结 簇识别 簇识别给出了聚类结果的含义 假定有一些数据 簇识别会告诉我们这些簇到底都是些什么 聚类与分类的区别 分类的目标事先
  • mavoneditor 显示html,mavonEditor

    mavonEditor 基于Vue的markdown编辑器 example 图片展示 PC Install mavon editor 安装 npm install mavon editor save Use 如何引入 index js 全局
  • CSS基础-position: absolute绝对定位的默认位置

    绝对定位position的值为absolute时的默认位置 前言 今天上午练习定位时发现了这么一个东西 元素设置为绝地定位后不给它添加top时是正常的我想要的结果 添加top后还需要精确的计算 正文 感觉你也应该开始好奇默认值是啥了 来一起
  • Windows下使用AcroRd32.exe(Adobe Acrobat Reader)打开PDF文件

    以下命令用于打开路径名为filename的PDF文件 acroRd32 exe filename 以下命令用于打开路径名为filename的PDF文件 并直接翻到第x页 acroRd32 exe a page x filename 例如 将
  • [记录]_运行.exe提示缺少MSVCP140_1.dll文件的解决办法

    在安装完成PySide2之后 点运行designer exe 总是提示缺少MSVCP140 1 dll文件 根据网上说法 是要去 https support microsoft com zh cn help 2977003 the late
  • Tensorboard的基本使用

    文章目录 一 一个简单例子 二 组件介绍 三 栏目介绍 3 0 graphs 3 1 scalars 3 2 images 3 3 audio 3 4 histograms 3 5 distributions 3 6 projector 3
  • Android Studio 工具:Lint 代码扫描工具(含自定义lint)

    转载 https www jianshu com p a0f28fbef73f 什么是 Lint Android Lint 是 SDK Tools 16 ADT 16 开始引入的一个代码扫描工具 通过对代码进行静态分析 可以帮助开发者发现代
  • django+xadmin 在线教育网站(三)

    在此之前我们已成功的使用xadmin将后台管理系统搭建起来了 接下来 开始我们后台的功能处理 首先是登录功能 登录功能 1 把html文件中index html和login html拷贝到templates文件夹内 2 新建static目录
  • 分布式流水号生成器

    引用http stor 51cto com art 201711 558600 htm的最终方案实现 使用数据库自增id 作为序列 使用支持多个服务 1 使用 REPLACE INTO SEQUENCE GENERATOR TABLE st
  • 详解TCP如何确保可靠传输(确认应答,重传机制,滑动窗口,流量控制)

    TCP确保可靠传输的机制 TCP协议格式 TCP的可靠传输 检验和 确认应答 序列号 重传机制 超时重传 RTO超时时间设置 快速重传 选择确认 SACK D SACK 滑动窗口 窗口大小 流量控制 窗口关闭 探测 糊涂窗口综合症 累计确认
  • 计算机技术应用广泛以下属于科学计算方面,2016年12月计算机二级MSoffice选择题习题...

    2016年12月计算机二级MSoffice选择题习题 计算机等级考试要取得好成绩平时一定要多加练习 提高做题技巧和速度 下面是小编为大家整理的2016年12月计算机二级MSoffice选择题习题 希望对大家有帮助 选择题 1 一棵二叉树中共
  • 前端面试官会问的问题

    前言 面试的多了才会发现面试官问的也就是那几个问题 因为面试后面有技术审核员 所以面试的时候专业知识占少部分 大部分是看你这个人怎么样 下面我总结了下对面试的经验 1 自我介绍 2 工作经历 3 现居地 4 实习了多久 5 第一家公司多少人
  • 算法设计-回溯法——装载问题

    算法介绍 回溯法 回溯法又称试探法 回溯法的基本做法是深度优先搜索 是一种组织得井井有条的 能避免不必要重复搜索的穷举式搜索算法 回溯算法的基本思想 从一条路往前走 能进则进 不能进则退回来 换一条路再试 问题实例 问题描述 题目 用回溯法
  • 杭电计算机考研(初试+复试)经验分享

    GitHub KolinHuang 个人博客 KolHuang Blog 欢迎交流 写在前头 离复试结束已经快半个月了 现在才想起来写这么一篇经验贴 供广大考研人参考参考 本人报考的是杭州电子科技大学的计算机专硕 本科专业是物联网 算半个跨
  • fiddler抓包第一课--手机数据抓包

    以前有学过fiddler 但是也只是安装下软件 听了一节课 没实际用过的东西 只是似懂非懂 昨天开发让我测手机APP 因为有一个原因选择不出来 问了前端 说需要抓包 问我会不会 我刚想开口说不会 但是 我突然想到 这不就是实践和学习的机会嘛
  • sqoop-export

    Sqoop工具模块之sqoop export 一 介绍 该export工具将一组文件从HDFS导入RDBMS 目标表必须已经存在于数据库中 根据用户指定的分隔符读取输入文件并将其解析为一组记录 1 模式 sqoop export有三种模式
  • DC综合基本概念:all_register -clock $clock_name

    综合中抓取某个时钟下所有的sink pin或者sink dff 可以使用 抓出所有的sink dff all register clock clock name 抓出所有sink dff 的clock pin foreach in coll
  • python的学习心得

    因为疫情 2020年寒假有点长 估计大部分人在家都憋坏了 人总是闲不住的 想要搞点事 于是我又捡起了那本 利用python进行数据分析 发现都能看懂 但是自己还没写过一个像样的程序 不写一个程序 总觉着有点遗憾 于是开启了一个全新的世界 既
  • SptringBoot第三讲(SpringBoot配置文件之properties application. properties)

    在Spring Boot中已经给创建好的application properties 中创建如下 server port 8081 idea使用的是utf 8 在Setting File Encodings utf 8 后边打上对号 配置p
  • 汇编中有符号与无符号数的区分

    origin http blog chinaunix net uid 28458801 id 3576608 html 转载自 http hi baidu com asmsky blog item 7290d20076cab6da277fb