zoukankan      html  css  js  c++  java
  • 汇编语言学习(814)

    1.1 汇编语言的由来及其特点

    1.1.1 机器语言

    机器指令是CPU能直接识别并执行的指令,它的表现形式是二进制编码。机器指令通常由操作码和操作数两部分组成,操作码指出该指令所要完成的操作,即指令的功能,操作数指出参与运算的对象,以及运算结果所存放的位置等。

    由于机器指令与CPU紧密相关,所以,不同种类的CPU所对应的机器指令也就不同,而且它们的指令系统往往相差很大。但对同一系列的CPU来说,为了满足各型号之间具有良好的兼容性,要做到:新一代CPU的指令系统必须包括先前同系列CPU的指令系统。只有这样,先前开发出来的各类程序在新一代CPU上才能正常运行。

    机器语言是用来直接描述机器指令、使用机器指令的规则等。它是CPU能直接识别的唯一一种语言,也就是说,CPU能直接执行用机器语言描述的程序。

    用机器语言编写程序是早期经过严格训练的专业技术人员的工作,普通的程序员一般难以胜任,而且用机器语言编写的程序不易读、出错率高、难以维护,也不能直观地反映用计算机解决问题的基本思路。

    由于用机器语言编写程序有以上诸多的不便,现在几乎没有程序员这样编写程序了。

    1.1.2 汇编语言

    虽然用机器语言编写程序有很高的要求和许多不便,但编写出来的程序执行效率高,CPU严格按照程序员的要求去做,没有多余的额外操作。所以,在保留“程序执行效率高”的前提下,人们就开始着手研究一种能大大改善程序可读性的编程方法。

    为了改善机器指令的可读性,选用了一些能反映机器指令功能的单词或词组来代表该机器指令,而不再关心机器指令的具体二进制编码。与此同时,也把CPU内部的各种资源符号化,使用该符号名也等于引用了该具体的物理资源。

    如此一来,令人难懂的二进制机器指令就可以用通俗易懂的、具有一定含义的符号指令来表示了,于是,汇编语言就有了雏型。现在,我们称这些具有一定含义的符号为助忆符,用指令助忆符、符号地址等组成的符号指令称为汇编格式指令(或汇编指令)。

    汇编语言是汇编指令集、伪指令集和使用它们规则的统称。伪指令是在程序设计时所需要的一些辅助性说明指令,它不对应具体的机器指令,有关内容在以后的各章节中会有详细叙述,在此不展开介绍。

    用汇编语言编写的程序称为汇编语言程序,或汇编语言源程序,在本教材中或特定的环境下,也可简称为源程序。汇编语言程序要比用机器指令编写的程序容易理解和维护。

    1.1.3 汇编程序

    用汇编语言编写的程序大大提高了程序的可读性,但失去了CPU能直接识别的特性。例如用汇编语言书写的指令:MOV AX, BX,CPU不会知道这几个字符所表达出来的功能,但程序员一看就知道:要求CPU把寄存器BX的值传送给寄存器AX。

    把机器指令符号化增加了程序的可读性,但引起了如何让CPU知道程序员的用意,并按照其要求完成相应操作的问题。解决该问题就需要一个翻译程序,它能把汇编语言编写的源程序翻译成CPU能识别的机器指令序列。这里,我们称该翻译程序为汇编程序。

    汇编程序能把左边汇编语言源程序翻译成右边的机器指令序列。其中,把汇编语言指令“MOV AX, BX”和“ADD AX, 5”分别转换成机器指令89D8H和050500H,而后者都是CPU能直接识别的,所以,可执行它们

    1.1.4 汇编语言的主要特点

    一方面,汇编语言指令是用一些具有相应含义的助忆符来表达的,所以,它要比机器语言容易掌握和运用,但另一方面,它要直接使用CPU的资源,相对高级程序设计语言来说,它又显得难掌握。

    汇编语言程序归纳起来大概有以下几个主要特性。

    1、与机器相关性

    汇编语言指令是机器指令的一种符号表示,而不同类型的CPU有不同的机器指令系统,也就有不同的汇编语言,所以,汇编语言程序与机器有着密切的关系。

    由于汇编语言程序与机器的相关性,所以,除了同系列、不同型号CPU之间的汇编语言程序有一定程度的可移植性之外,其它不同类型(如:小型机和微机等)CPU之间的汇编语言程序是无法移植的,也就是说,汇编语言程序的通用性和可移植性要比高级语言程序低。

    2、执行的高效率

    正因为汇编语言有“与机器相关性”的特性,程序员用汇编语言编写程序时,可充分发挥自己的聪明才智,对机器内部的各种资源进行合理的安排,让它们始终处于最佳的使用状态,这样做的最终效果就是:程序的执行代码短,执行速度快。

    现在,高级语言的编译程序在进行寄存器分配和目标代码生成时,也都有一定程度的优化(在后续课程《编译原理》的有关章节会有详细介绍),但由于所使用的“优化策略”要适应各种不同的情况,所以,这些优化策略只能在宏观上,不可能在微观上、细节上进行优化。而用汇编语言编写程序几乎是程序员直接在写执行代码,程序员可以在程序的每个具体细节上进行优化,这也是汇编语言程序执行高效率的原因之一。3、编写程序的复杂性

    汇编语言是一种面向机器的语言,其汇编指令与机器指令基本上一一对应,所以,汇编指令也同机器指令一样具有功能单一、具体的特点。要想完成某件工作(如计算:A+B+C等),就必须安排CPU的每步工作(如:先计算A+B,再把C加到前者的结果上)。另外,在编写汇编语言程序时,还要考虑机器资源的限制、汇编指令的细节和限制等等。

    由于汇编语言程序要安排运算的每一个细节,这就使得编写汇编语言程序比较繁琐、复杂。一个简单的计算公式或计算方法,也要用一系列汇编指令一步一步来实现。

    4、调试的复杂性

    在通常情况下,调试汇编语言程序要比调试高级语言程序困难,其主要原因有四:

     

    汇编语言指令涉及到机器资源的细节,在调试过程中,要清楚每个资源的变化情况;

     

    程序员在编写汇编语言程序时,为了提高资源的利用率,可以使用各种实现技巧,而这些技巧完全有可能破坏程序的可读性。这样,在调试过程中,除了要知道每条指令的执行功能,还要清楚它在整个解题过程中的作用;

     

    高级语言程序几乎不显式地使用“转移语句”,但汇编语言程序要用到大量的、各类转移指令,这些跳转指令大大地增加了调试程序的难度。如果在汇编语言程序中也强调不使用“转移指令”,那么,汇编语言程序就会变成功能单调的顺序程序,这显然是不现实的;

     

    调试工具落后,高级语言程序可以在源程序级进行符号跟踪,而汇编语言程序只能跟踪机器指令。不过,现在这方面也有所改善,CV(CodeView)、TD(Turbo Debug)等软件也可在源程序级进行符号跟踪了。

    1.1.5 汇编语言的使用领域

    综上所说,汇编语言的特点明显,其诱人的优点直接导致其严重的缺点,其“与机器相关”和“执行的高效率”导致其可移植性差和调试难。所以,我们在选用汇编语言时要根据实际的应用环境,尽可能避免其缺点对整个应用系统的影响。

    下面简单列举几个领域以示说明,但不要把它们绝对化。

    1、适用的领域

    要求执行效率高、反应快的领域,如:操作系统内核,工业控制,实时系统等;

    系统性能的瓶颈,或频繁被使用子程序或程序段;

    与硬件资源密切相关的软件开发,如:设备驱动程序等;

    受存储容量限制的应用领域,如:家用电器的计算机控制功能等;

    没有适当的高级语言开发环境。

    2、不宜使用的领域

    大型软件的整体开发;

    没有特殊要求的一般应用系统的开发等

    1.2 数据的表示和类型

    在用汇编语言进行程序设计时,程序员可以直接访问内存,对数据在存储器内的表示形式要有一个清晰的认识。下面,我们只简单介绍本课程所要用到的数据表示知识,为后面的学习作一点必要的准备。

    有关“数据表示”的详细内容请参阅《计算机组成原理》中的相关章节。

    1.2.1 数值数据的表示

    (1)、二进制

    在计算机内,数值是用二进制来表示的,每个二进制数按权相加就可得到其十进制数值。在书写二进制时,为了区别,在数据后面紧跟一个字母B。

    二进制的一般表现形式为:bn-1…b1b0B,其代表数值:bn-12n-1+…+b121+b020

    数据的二进制表示形式简单、明了,但它书写起来比较长,所以,通常情况下,我们在程序中不直接用二进制来书写具体的数值,而改用八进制、十进制或十六进制。

    (2)、八进制

    八进制是一种二进制的变形,三位二进制可变为一位八进制,反之也然。八进制的表示元素是:0、1、…、7。在书写时,为了区别,在数据后面紧跟一个字母Q。如:1234Q、7654Q、54Q等都是八进制。

    八进制数在程序中的使用频率不高。

    (3)、十进制

    十进制是我们最熟悉的一种数据表示形式,它的基本元素是:0、1、…、9。在书写时,为了区别,在数据后面紧跟一个字母D。在程序中经常用十进制来表示数据。

    (4)、十六进制

    十六进制是另一种二进制的变形,四位二进制可变为一位十六进制,反之也然。十六进制的基本元素是:0、1、…、9、A、B、…、F(字母小写也可以),其中:字母A、B、…、F依次代表10、11、…、15。

    在书写时,为了区别,在数据后面紧跟一个字母H。当十六进制数的第一个字符是字母时,在第一个字符之前必须添加一个‘0’。如:100H、56EFH、0FFH、0ABCDH等都是十六进制数。

    十六进制在程序中的使用频率很高。

    (5)、数值进制的总结和相互转换

    表1.1 各种进制及其字符表示

    进制

    字符

    例子

    备注

    二进制

    B/Y(*)

    1010B、1011B

    (*):字符Y、O和T是宏汇编MASM系统所增加的进制表示符。

    八进制

    Q/O

    1234Q、311Q

    十进制

    D/T

    1234D、512D

    十六进制

    H

    1234H、1011H

    下面是各进制数据之间进行转换的控件,浏览者通过它可很好地掌握这些进制之间的转换方法。当十进制转化为其它进制时,浏览者还可进行实际的练习操作。

    (6)、数的补码表示法

    在计算机内,为了表示正负数,并便于进行各种算术运算,对有符号数采用二进制的补码表示形式。

    补码的最高位用来表示正负数:0—正数,1—负数。

    正数的补码是其自身的二进制形式,负数的补码是把其正数的二进制编码变“反”,再加1而得。

    (7)、二进制数的符号扩展

    在汇编语言中,我们经常要对字/字节的数据进行操作。当把“字节”转换成“字”,或“字”转换成“双字”时,就需要进行符号扩展。符号扩展的具体操作就是把已知信息的最高位扩展到所有更高位。

    例1.1 把8位补码01011010、10101100分别扩展成16位补码。
    解:根据符号扩展的含义,“字节→字”的具体扩展结果如下:

     

    01011010

     

    10101100

    00000000

    01011010

    11111111

    10101100

    例1.2 把16位补码0101101111001010、1010111101011011别扩展成32位补码。
    解:根据符号扩展的含义,“字→双字”的具体扩展结果如下:

     

    0101101111001010

     

    1010111101011011

    0000000000000000

    0101101111001010

    1111111111111111

    1010111101011011

    (8)、n位二进制的表示范围

    n位二进制所能表示的无符号整数的范围:0≤x≤2n-1。
      n位二进制所能表示的有符号整数(补码表示)的范围:-2n-1(此处有错,是2的n次方)≤x≤2n-1-1。

    在汇编语言中,常用到n为8和16时的数值范围:

    n=8时,无符号整数的范围:0~255,有符号整数的范围:-128~127;
    n=16时,无符号整数的范围:0~65535,有符号整数的范围:-32768~32767。

    (9)、BCD码

    通常,我们习惯用十进制表示的数据,但计算机是用二进制来表示数据的,这就需要进行数值进制之间的转换。我们把每位十进制数转换二进制的编码,简称为BCD码(Binary Coded Decimal)。

    BCD码是用4位二进制编码来表示1位十进制数。这种编码方法有多种,但常用的编码是8421BCD编码,如表1.2所示。这种BCD编码实际上就是0~9的“等值”二进制数。

    表1.2  8421BCD编码列表

    十进制数字

    8421BCD码

    十进制数字

    8421BCD码

    0

    0000

    5

    0101

    1

    0001

    6

    0110

    2

    0010

    7

    0111

    3

    0011

    8

    1000

    4

    0100

    9

    1001

    用BCD码进行进制的转换时,是要求在二种进制的表现形式上快速转换,而不是要求在“数值相等”的含义快速转换。

    例1.3 求十进制数2000的BCD编码和其二进制数。

    解:2000的BCD编码是把每位上的数2、0、0、0分别转换为其对应的BCD编码:0010、0000、0000和0000,把它们合在一起就是2000的BCD编码:0010 0000 0000 0000。

    十进制数2000的二进制数是:11111010000,它们在数值上是相等的。

    1.2.2 非数值数据的表示

    计算机除了具有进行数值计算能力之外,还具有进行非数值计算的能力。现在,后者的应用领域已远远超过了前者的应用领域,如:文字处理、图形图象处理、信息检索、日常的办公管理等。所以,对非数值信息的编码就显得越加重要。

     

     

    1、ASCII码

    ASCII码(American Standard Code for Information Interchange)是目前应用极其广泛的一种信息编码,许多计算机系统都是采用它为字符进行编码。它是一种7位二进制编码。

    右表是ASCII码的具体编码方案。在该表中,对学习本课程有用的主要信息有:

    字符'0'~'9'是连续编码的,其编码的低4位就是该字符在十进制中的数值;

    小写字母的编码比大写字母的编码大,对应字母的编码之间相差20H(16进制的表示,32)。

    当然,从ASCII码表中还可看出其它有用信息,还有扩展的ASCII码等知识,但这些内容对学习本课程的帮助不明显,故不再叙述。有兴趣的读者可参阅其它书籍。

    表1.3 ASCII码的编码方案

      高位
     低位

    000

    001

    010

    011

    100

    101

    110

    111

    0000

    NUL

    DEL

    SP

    0

    @

    P

    `

    p

    0001

    SOH

    DC1

    !

    1

    A

    Q

    a

    q

    0010

    STX

    DC2

    2

    B

    R

    b

    r

    0011

    ETX

    DC3

    #

    3

    C

    S

    c

    s

    0100

    EOT

    DC4

    $

    4

    D

    T

    d

    t

    0101

    ENQ

    NAK

    %

    5

    E

    U

    e

    u

    0110

    ACK

    SYN

    &

    6

    F

    V

    f

    v

    0111

    BEL

    ETB

    7

    G

    W

    g

    w

    1000

    BS

    CAN

    (

    8

    H

    X

    h

    x

    1001

    HT

    EM

    )

    9

    I

    Y

    i

    y

    1010

    LF

    SUB

    *

    :

    J

    Z

    j

    z

    1011

    VT

    ESC

    +

    ;

    K

    [

    k

    {

    1100

    FF

    FS

     

    L

    l

    |

    1101

    CR

    GS

    -

    =

    M

    ]

    m

    }

    1110

    SO

    RS

    .

    N

    ^

    n

    ~

    1111

    SI

    US

    /

    ?

    O

    _

    o

    Del

    2、汉字编码

    ASCII码是针对英文的字母、数字和其它特殊字符进行编码的,它不能用于对汉字的编码。要想用计算机来处理汉字,就必须先对汉字进行适当的编码。我国在1981年5月对6000多个常用的汉字制定了交换码的国家标准,即:GB2312-80。该标准规定了汉字交换用的基本汉字字符和一些图形字符,它们共计7445个,其中汉字有6763个。该标准给定每个字符的二进制编码,即国标码。

    有关汉字编码的详细信息,请参阅其它有关书籍,在此不再介绍。

    1.2.3 基本的数据类型

    汇编语言所用到的基本数据类型为:字节、字、双字等,这些数据类型在以后的章节中都有相应的类型说明符。下面对它们进行最基本的描述。

    1、字节

    一个字节有8位二进制组成,其最高位是第7位,最低位是第0位,如右图所示。在表示有符号数时,最高位就是符号位。

    通常情况下,存储器按字节编址,读写存储器的最小信息单位就是一个字节。

     

    图1.2 字节数据类型示意图

    2、字

    由2个字节组成一个字,其最高位是第15位,最低位是第0位。高8位称为高字节,低8位称为低字节,如右图所示。

    字节和字是汇编语言程序中最常用的两种数据类型,也是最容易出错的数据类型。

     

    图1.3 字数据类型示意图

    3、双字

    用2个字(4个字节)来组成一个双字,其高16位称为高字,低16位称为低字,如右图所示。

    双字有较大的数据表示范围,它通常是为了满足数据的表示范围而选用的数据类型,也可用于存储远指针。

    字节、字和双字是汇编语言最常用的三种数据类型,下图表现出它们三者之间的组成关系。

     

     

    图1.5 字节、字和双字数据类型之间关系示意图

    4、四字

    由4个字(8个字节)组成一个四字类型,它总共有64个二进制位,当然,也就有更大的数据表示范围,但在汇编语言中很少使用该数据类型。

    5、十字节

    由10个字节组成一个十字节类型,它总共有80个二进制位。在汇编语言中很少使用该数据类型。

    6、字符串

    字符串是由若干个字节组成的,字节数不定,通常每个字节存储一个字符。该数据形式是汇编语言程序中经常使用的另一种数据形式。

    计算机中的负数是以其补码形式存在的 补码=原码取反+1
    一个字节有8位 可以表示的数值范围在 -128到+127
    用二进制表示也就是 10000000 - 01111111(注意:最高位表示符号)
    最高位是1的都是负数 最高位是0的都是正数
    如-7 原码是 10000111 然后取反(最高位是符合不用取反)得11111000
    加一 得11111001 那么-7的二进制数就是 11111001
    再如 -10 原码是 10001010 取反得 11110101 加一得 11110110
    那么-10的二进制数就是 11110110
    二进制数是逢二进一 只有0和1两个数字 没有2

     

    你说的“真值”可能指的就是它们的原码对应的值吧?那是这样的:

    补码00000000的真值是00000000,就是0;因为正数的反码、补码与原码一样;

    补码10000000的真值是10000000,就是-128;因为它是负数,要求它的原码,得对除符号位以外的各位取反再加1,就是对0000000取反成为1111111,再加1又成0000000了,符号位不变,所以得10000000。不过有一种观点认为-128这个数很特殊,没有反码与补码。知道实质就是了,不必太死扣定义。

    对于补码11111110,同样的办法对数据位取反加1来求原码:1111110取反得0000001,再加1得,0000001+0000001=0000010;符号位不变,再把它放上就是10000010;噢,它是-2!

    一个字节是8个二进制位,她可以表示256个不同的符号,而ASCII里面只有128个不同的符号,按理说7个二进制位就可以完全表达清楚了,那多出来的那一个二进制位是干什么用的啊
    计算机采用二进制的,8=2^3,通常最高位为符号位
    计算机中的位
      二进制数系统中,每个0或1就是一个位(bit),位是数据存储的最小单位。其中8bit就称为一个字节(Byte)。计算机中的CPU位数指的是CPU一次能处理的最大位数。例如32位计算机的CPU一次最多能处理32位数据。
      Bit,乃BInary digit(二进制数)位的缩写,是数学家John Wilder Tukey提议的术语(可能是1946年提出,但有资料称1943年就提出了)。这个术语第一次被正式使用,是在香农著名的《信息论》,即《通信的数学理论》(A Mathematical Theory of Communication)论文之第1页中。
    1字节8个二进制位是当时规定的,比较合理,便于储存和计算
    1Byte=8bit是先规定的,而ASCII是在有1字节=8位的前提下产生,ASCII占用1字节(如果按照你的想法将会很混乱,1个ASCII码字符占7/8个字节)

     

     

  • 相关阅读:
    POJ 1981 最大点覆盖问题(极角排序)
    POJ 1286 Pólya定理
    POJ 1830 高斯消元
    HDU 3364 高斯消元
    Educational Codeforces Round 42D. Merge Equals(STL)
    ZOJ 3955:Saddle Point(思维)
    POJ 3301:Texas Trip(计算几何+三分)
    SCUT 125 :笔芯回文(DP)
    ZOJ 3953:Intervals(优先队列+思维)
    Codeforces Gym101097I:Sticks (思维)
  • 原文地址:https://www.cnblogs.com/Zblogs/p/3258121.html
Copyright © 2011-2022 走看看