汇编语言笔记(一)

     很久没有来CSDN,今天突然看到CSDN管理员发来的信件。希望能够在这里和大家进行更好的交流,以促进相互的发展。

     学习汇编语言的目的有几个:

    [1]、更加深入的认识计算机原理

    [2]、学习JIT的实现原理

    [3]、能够理解并设计一门语言

    这方面想分三步走,第一:学习汇编的基础知识并作相关的练习。第二:学习Lightning的实现方法,从而弄清JIT的实现原理。第三:学习Qu语言的实现原理。并在此基础上做一些开发,写一个高性能的Web框架。

   我本身作为JAVA开发出身,对于底层技术有着深厚的兴趣。以上的一些学习,只作为个人兴趣。

   第一章:关于计算机整数的处理

   整数有两种表达方式:有符号和无符号。无符号数及正整数,它的表达方法很直接。例如整数200表达为一个字节的无符号整数,对应的二进制值为:11001000
   有符号整数表达起来比较复杂一些。例如 -56,+56表达起来很简单,可以表达为:00111000。而-56
在纸上可以简单的写为 -00111000。但是关键的问题是我们怎样在计算机中表达它呢?这个负符号又该怎么表示呢?
   这里通常有三种方法来表示,这三种方法中有一个共性,那就是都有一个符号位来表示是正数还是负数。
   这个符号为称为:"sign bit". 为0时表示正数,为1时表示负数。下面来看看三种表达方式:

   Signed magnitude
   这里不清楚具体术语,就用英文来表示了。这种方法很简单,把一个整数分成两部分,一部分即前面提到的符号位,
 一部分为整数值得表达。因此 -56 就表现为 10111000。这种方法一个字节表达的最大值为01111111 或 +127,最小值
 为11111111 或 -127。这种表现方法非常直观和简洁。
   但是它有它的缺点:
      第一: 0 整数有两种表现值 +0 (00000000) 和 -0 (10000000). 因为0及不是整数也不是负数。
   所以这两种表现应该在计算机看来应该是同样的值。因此这种表现方法是CPU对于0的操作变得复杂了。
    第二点: 普通的正负数预算变得复杂了。例如 10 加 -56 ,必须先把10 减 去 56得到才能得到。
 
  One’s complement
 
   第二种表达方法即:One’s complement。为什么叫One’s complement?故名思义,这种表现方法需要进行一次complement
   运算。所谓complement运算就是补运算:例如  56 (00111000) 进行一次complement运算后得到11000111. 因此 -56表示
   为11000111。注意:符号位经过一次complement之后自动的变为1表示负数。像第一种方法一样,第二种方法中0页有两种
   表现值+0 (00000000) 和 -0 (10000000).对于CPU在第二种方法中没有任何改观。第二种方法中提供了一种得到负数的技
   巧。当数字表现为十六进制的时候 例如 56表达为16进制 38,每一位和F相减即得到 C7,这和 -56的16进制数相吻合。
 
 
   Two’s complement
   前两种方法应用于早期的计算机中。现代的计算机运用第三种方法,也就是下面所要叙述的这种方法。该方法需要通过
   两次计算:
   1.整数进行一次complement运算。
   2.运算结果进行加1运算。
   还是以56(00111000)为例:经过第一个步骤得到11000111,然后对于11000111进行加1运算。
                            11000111
                                 + 1
                            --------------
                            11001000
  通过两次计算后 11001000 表示 -56。方法必须保证 -56经过否定可以得到原数。而第三种方法实际上是满足的 :
  -56经过一次complement运算得到了 00110111,然后再加1
                           
                            00110111
                                 + 1
                            --------------
                            00111000
   看一下结果,很奇怪的-56经过这样地运算得到了56。这个是比较有意思的.但是经过这样相对复杂的计算后才得到
   一个负数又有什么好处呢?那来看一下前面两种方法提到的弊端,在第三种方法中是否得到了解决。注意一点进位
   在第三种方法中是去掉的。
   第一:0 的表现形式:(00000000),那么它取负之后的结果又是什么呢?
          0 经过 一次complement运算得到了 11111111 ,然后再加1
 
                            11111111
                                 + 1
                            --------------
                          1 00000000
 
           可以看到,去掉进位后的结果正好是00000000。这对于计算机来讲表达形式是同一的,真是变化中的统一。也正好解决了第一种,第二种方法的弊端。
          用第三种方法,一个字节所表示的范围为 -128 - 127
                 两个字节十六BIt所表示的范围为 -32, 768 -- +32, 767
                 四个字节三十六位所表示的范围为 - 20亿左右 -- + 20亿左右


         CPU实际上并不能理解一个BYTE所要表示的是什么。同样汇编语言也不能理解
   高级语言所要表达的数据。数据的解析式通过不同的操作码来实现的。例如C语言
   他的编译器会把有符号数和无符号数编译成不同的操作码,以体现它们之间的差异。

第二章:有符号数据扩展

        一般来讲,在汇编语言中所有的数据都有固定的大小。通常并不需要改变数据
   存储的大小。通常减少大小是比较简单的,相反扩展就不是那么容易了。
             
         一:减少数据的大小

             减少数据大小只要把多余的bit去掉就可以了。下面是一个简单的例子
            mov ax, 0034h ; ax = 52 (stored in 16 bits)
            mov cl, al ; cl 现在的值为 ax 低八位的值

            当然如果整数以小的大小不能正确地表示的话。这种方法显然是不正确的。
           例如当AX = 0134h时。cl = 34h,这种方法可以应用于有符号数和无符号数。
           我们来看一下有符号数 如果 AX = FFFFh(-1) 这时 CL = FFh(-1).这个是
           正确的,但当FFFF表示无符号数时这种做法确是错误的。

     
         下面总结一下减少数据大小的规律,无符号数:被去掉的bit部分,不需保证他们全都是0
         有符号数:被去掉的bit部分,必须保证他们全部是0或者全部是1 。另外去掉的部分,和剩下的部分的第一位应该是相同的。符合上述规则数据的大小是可以减少的。
 
       二.增加数据大小
           增加大小相对来讲比较复杂一些,考虑一个十六进制的byte数值: FF. 如果把它扩展为一个字
,这个字应该怎样扩展呢?应该根据这个数值是有符号数,还是无符号数。如果FF是个无符号数的话
它应该扩展为00FF。但如果FF是个有符号数的话,它应该扩展为FFFF。
           一般来讲扩展无符号数,需要进行两个步骤,把该值放到扩展数的低位,高位用0补齐即可。
而有符号数则没有这么简单,首先一点它必须要保留符号位。这就意味着必须拷贝原数的符号位。也就是说在第二个步骤中,用符号位来补齐。看一下例子,有符号数FF的符号位为1,那么扩展数的高位就应该用1来补齐,即扩展后的数值为FFFF.有符号数5A,它的符号位为0。那么它扩展后的数值为005A。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值