汇编语言 订阅
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。在汇编语言中,用助记符代替机器指令的操作码,用地址符号或标号代替指令或操作数的地址。在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植。 [1] 展开全文
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。在汇编语言中,用助记符代替机器指令的操作码,用地址符号或标号代替指令或操作数的地址。在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植。 [1]
信息
产生年代
20世纪50年代
外文名
Assembly Language
编译方式
汇编
中文名
汇编语言
学    科
软件工程
汇编语言简介
汇编语言, 即第二代计算机语言,用一些容易理解和记忆的字母,单词来代替一个特定的指令,比如:用“ADD”代表数字逻辑上的加减,“ MOV”代表数据传递等等,通过这种方法,人们很容易去阅读已经完成的程序或者理解程序正在执行的功能,对现有程序的bug修复以及运营维护都变得更加简单方便。当计算机的硬件不认识字母符号,这时候就需要一个专门的程序把这些字符变成计算机能够识别的二进制数。因为汇编语言只是将机器语言做了简单编译,所以并没有根本上解决机器语言的特定性,所以汇编语言和机器自身的编程环境息息相关,推广和移植很难,但是还是保持了机器语言优秀的执行效率,因为他的可阅读性和简便性,汇编语言到现在依然是常用的编程语言之一。 [2]  汇编语言不像其他大多数的程序设计语言一样被广泛用于程序设计。在今天的实际应用中,它通常被应用在底层,硬件操作和高要求的程序优化的场合。驱动程序、嵌入式操作系统和实时运行程序都需要汇编语言。 [1] 
收起全文
精华内容
下载资源
问答
  • 手把手教你学习汇编语言——从入门到起飞

    万次阅读 多人点赞 2021-05-11 08:07:33
    关于这篇博客,笔者会尽量用最简单的方式教会大家汇编语言以便应付各种考试 有什么不足的忘大佬评论或私信指出。 汇编环境安装 汇编运行调试 汇编指令 希望大家看完这些找一些样例练习一下会学的更好,这里有一些...

    专接本交流群:1051749714 (有什么问题欢迎进群讨论)
    关于这篇博客,笔者会尽量用最简单的方式教会大家汇编语言以便应付各种考试
    有什么不足的忘大佬评论或私信指出。

    汇编环境安装
    汇编运行调试
    汇编指令

    希望大家看完这些找一些样例练习一下会学的更好,这里有一些练习题希望能帮助到大家
    汇编语言编程题总结

    汇编语言环境安装

    这里用的是Masm,相比较纯Dosbox会简单很多的
    汇编语言和CodeBlock安装包 密码:dqs9

    下载以后打开运行
    下一步
    在这里插入图片描述
    安装
    在这里插入图片描述
    完成即可
    在这里插入图片描述
    安装完成后打开,进来是默认的程序框

    在这里插入图片描述
    汇编语言运行的话,一定要保存文件到本地才可以运行,调试的话也需要先运行一下才能调试,否则就是调试的上次运行的程序。

    汇编运行调试

    当我们写好以后,它会提示我们先保存在运行
    在这里插入图片描述

    ctrl+s保存在一个地方,记得改名字,把 * 换成名字
    在这里插入图片描述

    再点击运行,出现这个就可以了,这是没有屏幕输出的程序,如果有屏幕输出,还会先输出程序输出的,在输出这一行。
    在这里插入图片描述

    (如果到时候一闪而过,说明你的程序有问题)
    下面会有提示哪一行有问题的,双击就会高亮显示那一行
    (笔者这个就是在AL后面多打了一个S)

    在这里插入图片描述

    运行可以了,那就大概说一下调试的过程(如果要调试的话,一定要先运行一遍才可以,否则就是调试的上一次运行的代码)

    调试的话,输入 T 是运行一步,你可以选择一步一步的运行,
    我们输入一个T 出来的划线位置就是下一次要运行的代码
    我们可以看到命令框第二个划线的 MOV AL,[0000H] 我们的AL赋值是12H 第二次AX的低四位还不是12H
    当我们再输入一个T,才是12H,也就是调试出来的代码是下一次将要运行的代码。
    在这里插入图片描述

    也许有些时候可能会觉得一步一步调试太麻烦了,这里也有直接跳转调试的

    我们之间输入一个U就会出现每一步代码所对应的数。
    在这里插入图片描述

    通过G 在写对应的号,就可以跳转到指定的位置
    在这里插入图片描述

    其他的话,可能会有更方便的,但是笔者认为这些就很够用了。

    软件安装运行调试大概就是到这里了,接下来我们来简述一下基本的命令语句吧

    汇编指令

    先来看一下基本的结构(分号后面的都是注释的,汇编语言用分号注释)

    DATAS SEGMENT	;数据段
        ;此处输入数据段代码  
    DATAS ENDS
     
    CODES SEGMENT	;代码段
        ASSUME CS:CODES,DS:DATAS		;数据段给DS,代码段给CS
    START:			;开始代码
        MOV AX,DATAS	;需要先把DATAAX寄存器,然后再从AXDSDATA不能直接给DS
        MOV DS,AX
        ;此处输入代码段代码
        MOV AH,4CH		;结束语句
        INT 21H
        
    CODES ENDS		;代码段结束
        END START	;结束代码
    
    

    先来说常用的命令符号,如果大家有什么其他命令符使用的话,可以评论或者私信我,我看到会尽快给大家展示出来如何使用

    MOV AL,BL
    这里就是把BL的值放到AL中。
    
     
    

    然后就是类似于C语言的函数
    这个函数就是起个名字加个分号
    汇编语言的函数没有结束的地方,一般如果需要结束的加,就要加一个跳转到其他地方
    如果没有跳转,他就会一直运行到下面

    DATA SEGMENT 
    A DB 12H	;定义两个变量
    B DB 24H
    DATA ENDS 
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	JMP EXIT	;这里就是直接跳转到EXIT  JMP就是跳转的方法
    	
    	MOV AL,A	;A->AL
    	MOV BL,B	;B->BL
    	MOV A,BL	;BL->A
    	MOV B,AL	;AL->B
    	 
    	 
    EXIT:
        MOV AH,4CH
        INT 21H
    CODES ENDS
        END START
    
    
    

    当然还有很多特别的JMP 也就是一些带标志位的 就是标志寄存器里面的六个状态位

    1、进位标志CF(Carry Flag)
    进位标志CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0使用该标志位的情况有:多字(字节)数的加减运算,无符号数的大小比较运算,移位操作,字(字节)之间移位,专门改变CF值的指令等。
    
    2、奇偶标志PF(Parity Flag)
    
    奇偶标志PF用于反映运算结果中“1”的个数的奇偶性。如果“1”的个数为偶数,则PF的值为1,否则其值为0。
    
    利用PF可进行奇偶校验检查,或产生奇偶校验位。在数据传送过程中,为了提供传送的可靠性,如果采用奇偶校验的方法,就可使用该标志位。
    
    3、辅助进位标志AF(Auxiliary Carry Flag)
    在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:
    
    (1)、在字操作时,发生低字节向高字节进位或借位时;
    (2)、在字节操作时,发生低4位向高4位进位或借位时。
    
    对以上6个运算结果标志位,在一般编程情况下,标志位CFZFSFOF的使用频率较高,而标志位PFAF的使用频率较低。
    
    4、零标志ZF(Zero Flag)
    零标志ZF用来反映运算结果是否为0。如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位。
    
    5、符号标志SF(Sign Flag)
    
    符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同。
    在微机系统中,有符号数采用补码表示法,所以,SF也就反映运算结果的正负号。运算结果为正数时,SF的值为0,否则其值为16、溢出标志OF(Overflow Flag)
    
    溢出标志OF用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围,则称为溢出,
    OF的值被置为1,否则,OF的值被清为0。 
    (有些时候,有些问题会问你是不是溢出了,这里有个巧计的方法,负数加负数是正数,正数加正数是负数,如果出现这种情况就是溢出了)
    

    然后衍生出来的就是几个条件跳转指令
    一般情况下,条件跳转上面要跟一些影响标志寄存器的命令

    
    JE   ;等于则跳转
    JNE  ;不等于则跳转
     
    JZ   ;0 则跳转
    JNZ  ;不为 0 则跳转
     
    JS   ;为负则跳转
    JNS  ;不为负则跳转
     
    JC   ;进位则跳转
    JNC  ;不进位则跳转
     
    JO   ;溢出则跳转
    JNO  ;不溢出则跳转
     
    JA   ;无符号大于则跳转
    JNA  ;无符号不大于则跳转
    JAE  ;无符号大于等于则跳转
    JNAE ;无符号不大于等于则跳转
     
    JG   ;有符号大于则跳转
    JNG  ;有符号不大于则跳转
    JGE  ;有符号大于等于则跳转
    JNGE ;有符号不大于等于则跳转
     
    JB   ;无符号小于则跳转
    JNB  ;无符号不小于则跳转
    JBE  ;无符号小于等于则跳转
    JNBE ;无符号不小于等于则跳转
     
    JL   ;有符号小于则跳转
    JNL  ;有符号不小于则跳转
    JLE  ;有符号小于等于则跳转
    JNLE ;有符号不小于等于则跳转
     
    JP   ;奇偶位置位则跳转
    JNP  ;奇偶位清除则跳转
    JPE  ;奇偶位相等则跳转
    JPO  ;奇偶位不等则跳转
    
    

    说完跳转类的指令,接下来我们看一看左移右移指令
    左移这种指令左移一位就是二进制左移一位,也就是乘2的操作。

    SHL(Shift Left)SAL(Shift Arithmetic Left): 每位左移, 低位补 0,  高位进 CF
    SHR(Shift Right)     : 每位右移, 低位进 CF, 高位补 0
    SAR(Shift Arithmetic Right)     : 每位右移, 低位进 CF, 高位不变(也就是高位复制到第二位)
    
    使用的时候就是 
    SHL AL,1
    左移一位
    如果移动的位数大于1位,就要放到CX

    循环左移右移

    ;ROL(Rotate Left): 循环左移, 高位到低位并送 CF
    ;ROR(Rotate Right): 循环右移, 低位到高位并送 CF
    ;RCL(Rotate through Carry Left): 循环左移, 进位值(CF)到低位, 高位进 CF
    ;RCR(Rotate through Carry Right): 循环右移, 进位值(CF)到高位, 低位进 CF
    
    使用的时候就是 
    ROL AL,1
    循环左移一位
    如果移动的位数大于1位,就要放到CX

    然后就是加减乘除

    加法add和adc、inc
    ADD AL,BL
    ALBL加起来放到AL
    
    ADC的话就是ADD的运算在家一个CF状态位的值,
    
    INC AL
    AL1
    
    
    减法sub和sbb、dec
    SUB 对应ADD
    SBB 对应ADC
    DEC 对应INC
    用法都是一样的,就是一个是加一个是减
    
    乘法mul和imul
    MUL是无符号乘法
    MUL 8位的   就是AL乘这个数放到AL 高位放到AH
    MUL 16位的   就是AX乘这个数放到AX中	高位放到DX
    
    除法div和idiv
    DIV是无符号除法
    DIV 8位的   就是 AX除这个数,商放AL  余数放AH
    DIV16位的   就是(DX:AX)除这个数,商放AX  余数放DX
    
    异或运算XOR
    
    XOR AL,BL
    ALBL异或运算放入AL
    
    与运算AND   或运算OR都是一样的
    
    然后就是CMPTEST
    CMP 就是对应的减法,但是这个不会影响AL的值,他只会影响状态标志位
    TEST 就是AND的用法,也是不会影响AL,只影响状态标志位
    
    

    最后就是DOS功能的输入输出

    字符输入输出
    
    DATA SEGMENT 
    	 
    DATA ENDS 
    
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV AH,01H	 ;键盘输入的时候,给AH  1
    	INT 21H		 ;然后INT 21H调用,默认输入到ALMOV DL,AL	 ;CMD窗口输出的时候,要把输出的放到DLMOV AH,02H	 ;AH  2
    	INT 21H
    	
    	 
    	 
    EXIT:
       		MOV AH,4CH
            INT 21H
    CODES ENDS
        END START
    
    字符串输入输出
    
    DATA SEGMENT 
    	 BUF DB 20 DUP('$')
    	 BUFF DB 'Hello World!$'
    DATA ENDS 
    
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV DX,OFFSET BUF	;把偏移地址给DX,也可以用 LEA DX,BUF  二者皆可
    	MOV AH,0AH	 ;键盘输入的时候,给AH  10
    	INT 21H		 ;然后INT 21H调用,默认输入到BUFMOV DX,OFFSET BUFF	 ;CMD窗口输出的时候,要把输出偏移地址放到DXMOV AH,09H	 ;AH  2
    	INT 21H
    	
    	 
    	 
    EXIT:
       		MOV AH,4CH
            INT 21H
    CODES ENDS
        END START
    
    展开全文
  • 汇编语言

    千次阅读 2019-09-18 21:52:55
    汇编语言 汇编语言是一类语言,ARM,MIPS,X86。 汇编语言与CPU联系紧密。但是可移植性差。 Li $t1 , 1 # 把1放到t1寄存器里面 add $t0 , $t1 ,2 # 2加上ti里面的放到t0中 ...

    汇编语言

    汇编语言是一类语言,ARM,MIPS,X86。
    汇编语言与CPU联系紧密。但是可移植性差。

     Li $t1 , 1   # 把1放到t1寄存器里面
     add $t0 , $t1 ,2  # 2加上ti里面的放到t0中
    
    展开全文
  • 什么是汇编语言

    万次阅读 多人点赞 2018-11-19 21:21:37
    汇编语言(assembly language)是一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。在汇编语言中,用助记符(Mnemonics)代替机器指令的操作码,用地址符号(Symbol)或标号...

           汇编语言(assembly language)是一种用于电子计算机微处理器微控制器或其他可编程器件的低级语言,亦称为符号语言。在汇编语言中,助记符(Mnemonics)代替机器指令操作码,用地址符号(Symbol)或标号(Label)代替指令或操作数地址。在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。普遍地说,特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植。

           许多汇编程序为程序开发、汇编控制、辅助调试提供了额外的支持机制。有的汇编语言编程工具经常会提供宏,它们也被称为宏汇编器。

           汇编语言不像其他大多数的程序设计语言一样被广泛用于程序设计。在今天的实际应用中,它通常被应用在底层,硬件操作和高要求的程序优化的场合。驱动程序、嵌入式操作系统和实时运行程序都需要汇编语言。

            Microsoft 宏汇编器(称为 MASM)是windows下常用的汇编器。Microsoft Visual Studio 的大多数版本(专业版,旗舰版,精简版……)都包含 MASM。在运行 Microsoft Windows 的 x86 系统中,其他一些有名的汇编器包括:TASM(Turbo 汇编器),NASM(Netwide 汇编器)和 MASM32(MASM 的一种变体)。GAS(GNU 汇编器)和 NASM 是两种基于 Linux 的汇编器。在这些汇编器中,NASM 的语法与 MASM 的最相似。汇编语言最古老的编程语言,在所有的语言中,它与原生机器语言最为接近。它能直接访问计算机硬件,要求用户了解计算机架构和操作系统。

    什么是汇编器和链接器?

           汇编器(assembler)是一种工具程序,用于将汇编语言源程序转换为机器语言。链接器(linker)也是一种工具程序,它把汇编器生成的单个文件组合为一个可执行程序。还有一个相关的工具,称为调试器(debugger),使程序员可以在程序运行时,单步执行程序并检查寄存器和内存状态。

    MASM 能创建哪些类型的程序?

    32 位保护模式(32-Bit Protected Mode)32 位保护模式程序运行于所有的 32 位和 64 位版本的 Microsoft Windows 系统。它们通常比实模式程序更容易编写和理解。从现在开始,将其简称为 32 位模式。
    64 位模式(64-Bit Mode)64 位程序运行于所有的 64 位版本 Microsoft Windows 系统。
    16 位实地址模式(16-Bit Real-Address Mode)16 位程序运行于 32 位版本 Windows 和嵌入式系统。 64 位 Windows 不支持这类程序。

    汇编语言与机器语言有什么关系?

           机器语言(machine language)是一种数字语言, 专门设计成能被计算机处理器(CPU)理解。所有 x86 处理器都理解共同的机器语言。
    汇编语言(assembly language)包含用短助记符如 ADD、MOV、SUB 和 CALL 书写的语句。汇编语言与机器语言是一对一(one-to-one)的关系:每一条汇编语言指令对应一条机器语言指令。寄存器(register)是 CPU 中被命名的存储位置,用于保存操作的中间结果

    C++ 和 Java 与汇编语言有什么关系?

           高级语言如 Python、C++ 和 Java 与汇编语言和机器语言的关系是一对多(one-to-many)。比如,C++ 的一条语句就会扩展为多条汇编指令或机器指令。

    汇编语言可移植吗?

    一种语言,如果它的源程序能够在各种各样的计算机系统中进行编译和运行,那么这种语言被称为是可移植的(portable)。
    例如,一个 C++ 程序,除非需要特别引用某种操作系统的库函数,否则它就几乎可以在任何一台计算机上编译和运行。Java 语言的一大特点就是,其编译好的程序几乎能在所有计算机系统中运行。
    汇编语言不是可移植的,因为它是为特定处理器系列设计的。目前广泛使用的有多种不同的汇编语言,每一种都基于一个处理器系列。
    对于一些广为人知的处理器系列如 Motorola 68x00、x86、SUN Sparc、Vax 和 IBM-370,汇编语言指令会直接与该计算机体系结构相匹配,或者在执行时用一种被称为微代码解释器(microcode interpreter)的处理器内置程序来进行转换。

    发展历程

           说到汇编语言的产生,首先要讲一下机器语言。机器语言是机器指令的集合。机器指令展开来讲就是一台机器可以正确执行的命令。电子计算机的机器指令是一列二进制数字。计算机将之转变为一列高低电平,以使计算机的电子器件受到驱动,进行运算。

           上面所说的计算机指的是可以执行机器指令,进行运算的机器。这是早期计算机的概念。在我们常用的PC机中,有一个芯片来完成上面所说的计算机的功能。这个芯片就是我们常说的CPU(Central Processing Unit,中央处理单元)。每一种微处理器,由于硬件设计和内部结构的不同,就需要用不同的电平脉冲来控制,使它工作。所以每一种微处理器都有自己的机器指令集,也就是机器语言。CPU 只负责计算,本身不具备智能。你输入一条指令(instruction),它就运行一次,然后停下来,等待下一条指令。这些指令都是二进制的,称为操作码(opcode),比如加法指令就是00000011。编译器的作用,就是将高级语言写好的程序,翻译成一条条操作码。对于人类来说,二进制程序是不可读的,根本看不出来机器干了什么。为了解决可读性的问题,以及偶尔的编辑需求,就诞生了汇编语言。汇编语言是二进制指令的文本形式,与指令是一一对应的关系。比如,加法指令00000011写成汇编语言就是 ADD。只要还原成二进制,汇编语言就可以被 CPU 直接执行,所以它是最底层的低级语言

           早期的程序设计均使用机器语言。程序员们将用0, 1数字编成的程序代码打在纸带或卡片上,1打孔,0不打孔,再将程序通过纸带机或卡片机输入计算机,进行运算。这样的机器语言由纯粹的0和1构成,十分复杂,不方便阅读和修改,也容易产生错误。程序员们很快就发现了使用机器语言带来的麻烦,它们难于辨别和记忆,给整个产业的发展带来了障碍,于是汇编语言产生了。

           汇编语言的主体是汇编指令。汇编指令和机器指令的差别在于指令的表示方法上。汇编指令是机器指令便于记忆的书写格式。

    操作:寄存器BX的内容送到AX中
    1000100111011000              机器指令
    mov ax,bx                    汇编指令

           此后,程序员们就用汇编指令编写源程序。可是,计算机能读懂的只有机器指令,那么如何让计算机执行程序员用汇编指令编写的程序呢?这时,就需要有一个能够将汇编指令转换成机器指令的翻译程序,这样的程序我们称其为编译器。程序员用汇编语言写出源程序,再用汇编编译器将其编译为机器码,由计算机最终执行。 

    语言特点

           汇编语言是直接面向处理器(Processor)的程序设计语言。处理器是在指令的控制下工作的,处理器可以识别的每一条指令称为机器指令。每一种处理器都有自己可以识别的一整套指令,称为指令集。处理器执行指令时,根据不同的指令采取不同的动作,完成不同的功能,既可以改变自己内部的工作状态,也能控制其它外围电路的工作状态。

           汇编语言的另一个特点就是它所操作的对象不是具体的数据,而是寄存器或者存储器,也就是说它是直接和寄存器和存储器打交道,这也是为什么汇编语言的执行速度要比其它语言快,但同时这也使编程更加复杂,因为既然数据是存放在寄存器或存储器中,那么必然就存在着寻址方式,也就是用什么方法找到所需要的数据。例如上面的例子,我们就不能像高级语言一样直接使用数据,而是先要从相应的寄存器AX、BX 中把数据取出。这也就增加了编程的复杂性,因为在高级语言中寻址这部分工作是由编译系统来完成的,而在汇编语言中是由程序员自己来完成的,这无异增加了编程的复杂程度和程序的可读性。

           再者,汇编语言指令是机器指令的一种符号表示,而不同类型的CPU 有不同的机器指令系统,也就有不同的汇编语言,所以,汇编语言程序与机器有着密切的关系。所以,除了同系列、不同型号CPU 之间的汇编语言程序有一定程度的可移植性之外,其它不同类型(如:小型机和微机等)CPU 之间的汇编语言程序是无法移植的,也就是说,汇编语言程序的通用性和可移植性要比高级语言程序低。

           正因为汇编语言有“与机器相关性”的特性,程序员用汇编语言编写程序时,可充分对机器内部的各种资源进行合理的安排,让它们始终处于最佳的使用状态。这样编写出来的程序执行代码短、执行速度快。汇编语言是各种编程语言中与硬件关系最密切、最直接的一种,在时间和空间的效率上也最高的一种。

    总体特点

    1.机器相关性

           这是一种面向机器的低级语言,通常是为特定的计算机或系列计算机专门设计的。因为是机器指令的符号化表示,故不同的机器就有不同的汇编语言。使用汇编语言能面向机器并较好地发挥机器的特性,得到质量较高的程序。

    2.高速度和高效率

           汇编语言保持了机器语言的优点,具有直接和简捷的特点,可有效地访问、控制计算机的各种硬件设备,如磁盘、存储器、CPUI/O端口等,且占用内存少,执行速度快,是高效的程序设计语言

    3.编写和调试的复杂性

           由于是直接控制硬件,且简单的任务也需要很多汇编语言语句,因此在进行程序设计时必须面面俱到,需要考虑到一切可能的问题,合理调配和使用各种软、硬件资源。这样,就不可避免地加重了程序员的负担。与此相同,在程序调试时,一旦程序的运行出了问题,就很难发现。

    优点

    1、因为用汇编语言设计的程序最终被转换成机器指令,故能够保持机器语言的一致性,直接、简捷,并能像机器指令一样访问、控制计算机的各种硬件设备,如磁盘、存储器CPUI/O端口等。使用汇编语言,可以访问所有能够被访问的软、硬件资源。

    2、目标代码简短,占用内存少,执行速度快,是高效的程序设计语言,经常与高级语言配合使用,以改善程序的执行速度和效率,弥补高级语言在硬件控制方面的不足,应用十分广泛。

    缺点

    1、汇编语言是面向机器的,处于整个计算机语言层次结构的底层,故被视为一种低级语言,通常是为特定的计算机或系列计算机专门设计的。不同的处理器有不同的汇编语言语法和编译器,编译的程序无法在不同的处理器上执行,缺乏可移植性;

    2、难于从汇编语言代码上理解程序设计意图,可维护性差,即使是完成简单的工作也需要大量的汇编语言代码,很容易产生bug,难于调试;

    3、使用汇编语言必须对某种处理器非常了解,而且只能针对特定的体系结构和处理器进行优化,开发效率很低,周期长且单调。 

    语言组成

    数据传送指令

    这部分指令包括通用数据传送指令MOV、条件传送指令CMOVcc、堆栈操作指令PUSH/PUSHA/PUSHAD/POP/POPA/POPAD、交换指令XCHG/XLAT/BSWAP、地址或段描述符选择子传送指令LEA/LDS/LES/LFS/LGS/LSS等。注意,CMOVcc不是一条具体的指令,而是一个指令簇,包括大量的指令,用于根据EFLAGS寄存器的某些位状态来决定是否执行指定的传送操作。

    整数和逻辑运算指令

    这部分指令用于执行算术和逻辑运算,包括加法指令ADD/ADC、减法指令SUB/SBB、加一指令INC、减一指令DEC、比较操作指令CMP、乘法指令MUL/IMUL、除法指令DIV/IDIV、符号扩展指令CBW/CWDE/CDQE、十进制调整指令DAA/DAS/AAA/AAS、逻辑运算指令NOT/AND/OR/XOR/TEST等。

    移位指令

    这部分指令用于将寄存器或内存操作数移动指定的次数。包括逻辑左移指令SHL、逻辑右移指令SHR、算术左移指令SAL、算术右移指令SAR、循环左移指令ROL、循环右移指令ROR等。

    位操作指令

    这部分指令包括位测试指令BT、位测试并置位指令BTS、位测试并复位指令BTR、位测试并取反指令BTC、位向前扫描指令BSF、位向后扫描指令BSR等。

    条件设置指令

    这不是一条具体的指令,而是一个指令簇,包括大约30条指令,用于根据EFLAGS寄存器的某些位状态来设置一个8位的寄存器或者内存操作数。比如SETE/SETNE/SETGE等等。

    控制转移指令

    这部分包括无条件转移指令JMP、条件转移指令Jcc/JCXZ、循环指令LOOP/LOOPE/LOOPNE、过程调用指令CALL、子过程返回指令RET、中断指令INTn、INT3、INTOIRET等。注意,Jcc是一个指令簇,包含了很多指令,用于根据EFLAGS寄存器的某些位状态来决定是否转移;INT n是软中断指令,n可以是0到255之间的数,用于指示中断向量号。

    串操作指令

    这部分指令用于对数据串进行操作,包括串传送指令MOVS、串比较指令CMPS、串扫描指令SCANS、串加载指令LODS、串保存指令STOS,这些指令可以有选择地使用REP/REPE/REPZ/REPNE和REPNZ的前缀以连续操作。

    输入输出指令

    这部分指令用于同外围设备交换数据,包括端口输入指令IN/INS、端口输出指令OUT/OUTS。

    高级语言辅助指令

    这部分指令为高级语言的编译器提供方便,包括创建栈帧的指令ENTER和释放栈帧的指令LEAVE。

    控制和特权指令

    这部分包括无操作指令NOP、停机指令HLT、等待指令WAIT/MWAIT、换码指令ESC、总线封锁指令LOCK、内存范围检查指令BOUND、全局描述符表操作指令LGDT/SGDT、中断描述符表操作指令LIDT/SIDT、局部描述符表操作指令LLDT/SLDT、描述符段界限值加载指令LSR、描述符访问权读取指令LAR、任务寄存器操作指令LTR/STR、请求特权级调整指令ARPL、任务切换标志清零指令CLTS、控制寄存器和调试寄存器数据传送指令MOV、高速缓存控制指令INVD/WBINVD/INVLPG、型号相关寄存器读取和写入指令RDMSR/WRMSR、处理器信息获取指令CPUID、时间戳读取指令RDTSC等。

    浮点和多媒体指令

    这部分指令用于加速浮点数据的运算,以及用于加速多媒体数据处理的单指令多数据(SIMD及其扩展SSEx)指令。这部分指令数据非常庞大,无法一一列举,请自行参考INTEL手册。

    虚拟机扩展指令

    这部分指令包括INVEPT/INVVPID/VMCALL/VMCLEAR/VMLAUNCH/VMRESUME/VMPTRLD/VMPTRST/VMREAD/VMWRITE/VMXOFF/VMON等。 

    相关技术

    汇编器

    典型的现代汇编器(assembler)建造目标代码,由解译组语指令集的易记码(mnemonics)到操作码(OpCode),并解析符号名称(symbolic names)成为存储器地址以及其它的实体。使用符号参考是汇编器的一个重要特征,它可以节省修改程序后人工转址的乏味耗时计算。基本就是把机器码变成一些字母而已,编译的时候再把输入的指令字母替换成为晦涩难懂机器码。

    编译环境

    用汇编语言等非机器语言书写好的符号程序称为源程序,汇编语言编译器的作用是将源程序翻译成目标程序。目标程序是机器语言程序,当它被安置在内存的预定位置上后,就能被计算机的CPU处理和执行。

    汇编的调试环境总的来说比较少,也很少有非常好的编译器。编译器的选择依赖于目标处理器的类型和具体的系统平台。一般来说,功能良好的编译器用起来应当非常方便,比如,应当可以自动整理格式、语法高亮显示,集编译、链接和调试为一体,方便实用。

    对于广泛使用的个人计算机来说,可以自由选择的汇编语言编译器有MASMNASMTASMGAS、FASM、RADASM等,但大都不具备调试功能。如果是为了学习汇编语言,轻松汇编因为拥有一个完善的集成环境,是一款非常适合初学者的汇编编译器。 

    发展前景

    汇编语言是机器语言的助记符,相对于比枯燥的机器代码易于读写、易于调试和修改,同时优秀的汇编语言设计者经过巧妙的设计,使得汇编语言汇编后的代码比高级语言执行速度更快,占内存空间少等优点,但汇编语言的运行速度和空间占用是针对高级语言并且需要巧妙设计,而且部分高级语言在编译后代码执行效率同样很高,所以此优点慢慢弱化。而且在编写复杂程序时具有明显的局限性,汇编语言依赖于具体的机型,不能通用,也不能在不同机型之间移植。常说汇编语言是低级语言,并不是说汇编语言要被弃之,相反,汇编语言仍然是计算机(或微机)底层设计程序员必须了解的语言,在某些行业与领域,汇编是必不可少的,非它不可适用。只是,现在计算机最大的领域为IT软件,也是我们常说的计算机应用软件编程,在熟练的程序员手里,使用汇编语言编写的程序,运行效率与性能比其它语言写的程序相对提高,但是代价是需要更长的时间来优化,如果对计算机原理及编程基础不扎实,反而增加其开发难度,实在是得不偿失,对比2010年前后的软件开发,已经是市场化的软件行业,加上高级语言的优秀与跨平台,一个公司不可以让一个团队使用汇编语言来编写所有的东西,花上几倍甚至几十倍的时间,不如使用其它语言来完成,只要最终结果不比汇编语言编写的差太多,就能抢先一步完成,这是市场经济下的必然结果。

     

    但是,迄今为止,还没有程序员敢断定汇编语言是不需要学的,同时,汇编语言(Assembly Language)是面向机器的程序设计语言,设计精湛的汇编程序员,部分已经脱离软件开发,挤身于工业电子编程中。对于功能相对小巧但硬件对语言设计要求苛刻的行业,如4位单片机,由于其容量及运算,此行业的电子工程师一般负责从开发设计电路及软件控制,主要开发语言就是汇编,c语言使用只占极少部分,而电子开发工程师是千金难求,在一些工业公司,一个核心的电子工程师比其它任何职员待遇都高,对比起来,一般电子工程师待遇是程序员的十倍以上。这种情况是因为21世纪以来,学习汇编的人虽然也不少,但是真正能学到精通的却不多,它相对于高级语言难学,难用,适用范围小,虽然简单,但是过于灵活,学习过高级语言的人去学习汇编比一开始学汇编的人难得多,但是学过汇编的人学习高级语言却很容易,简从繁易,繁从简难。对于一个全面了解微机原理的程序员,汇编语言是必修语言。

    实际应用

    随着现代软件系统越来越庞大复杂,大量经过了封装的高级语言如C/C++Pascal/Object Pascal也应运而生。这些新的语言使得程序员在开发过程中能够更简单,更有效率,使软件开发人员得以应付快速的软件开发的要求。而汇编语言由于其复杂性使得其适用领域逐步减小。但这并不意味着汇编已无用武之地。由于汇编更接近机器语言,能够直接对硬件进行操作,生成的程序与其他的语言相比具有更高的运行速度,占用更小的内存,因此在一些对于时效性要求很高的程序、许多大型程序的核心模块以及工业控制方面大量应用。 

    历史上,汇编语言曾经是非常流行的程序设计语言之一。随着软件规模的增长,以及随之而来的对软件开发进度和效率的要求,高级语言逐渐取代了汇编语言。但即便如此,高级语言也不可能完全替代汇编语言的作用。就拿Linux内核来讲,虽然绝大部分代码是用C语言编写的,但仍然不可避免地在某些关键地方使用了汇编代码。由于这部分代码与硬件的关系非常密切,即使是C语言也会显得力不从心,而汇编语言则能够很好扬长避短,最大限度地发挥硬件的性能。

    首先,汇编语言的大部分语句直接对应着机器指令,执行速度快,效率高,代码体积小,在那些存储器容量有限,但需要快速和实时响应的场合比较有用,比如仪器仪表和工业控制设备中。

    其次,在系统程序的核心部分,以及与系统硬件频繁打交道的部分,可以使用汇编语言。比如操作系统的核心程序段、I/O接口电路的初始化程序、外部设备的低层驱动程序,以及频繁调用的子程序动态连接库、某些高级绘图程序、视频游戏程序等等。

    再次,汇编语言可以用于软件的加密和解密、计算机病毒的分析和防治,以及程序的调试和错误分析等各个方面。

    最后,通过学习汇编语言,能够加深对计算机原理和操作系统等课程的理解。通过学习和使用汇编语言,能够感知、体会和理解机器的逻辑功能,向上为理解各种软件系统的原理,打下技术理论基础;向下为掌握硬件系统的原理,打下实践应用基础。

    附注:寄存器和内存模型

    学习汇编语言,首先必须了解两个知识点:寄存器和内存模型。

    先来看寄存器。CPU 本身只负责运算,不负责储存数据。数据一般都储存在内存之中,CPU 要用的时候就去内存读写数据。但是,CPU 的运算速度远高于内存的读写速度,为了避免被拖慢,CPU 都自带一级缓存和二级缓存。基本上,CPU 缓存可以看作是读写速度较快的内存。

    但是,CPU 缓存还是不够快,另外数据在缓存里面的地址是不固定的,CPU 每次读写都要寻址也会拖慢速度。因此,除了缓存之外,CPU 还自带了寄存器(register),用来储存最常用的数据。也就是说,那些最频繁读写的数据(比如循环变量),都会放在寄存器里面,CPU 优先读写寄存器,再由寄存器跟内存交换数据。

    寄存器不依靠地址区分数据,而依靠名称。每一个寄存器都有自己的名称,我们告诉 CPU 去具体的哪一个寄存器拿数据,这样的速度是最快的。有人比喻寄存器是 CPU 的零级缓存。

    1、寄存器的种类

    早期的 x86 CPU 只有8个寄存器,而且每个都有不同的用途。现在的寄存器已经有100多个了,都变成通用寄存器,不特别指定用途了,但是早期寄存器的名字都被保存了下来。

    EAX

    EBX

    ECX

    EDX

    EDI

    ESI

    EBP

    ESP

    上面这8个寄存器之中,前面七个都是通用的。ESP 寄存器有特定用途,保存当前 Stack 的地址。

    我们常常看到 32位 CPU、64位 CPU 这样的名称,其实指的就是寄存器的大小。32 位 CPU 的寄存器大小就是4个字节。

    2、内存模型:Heap

    寄存器只能存放很少量的数据,大多数时候,CPU 要指挥寄存器,直接跟内存交换数据。所以,除了寄存器,还必须了解内存怎么储存数据。

    程序运行的时候,操作系统会给它分配一段内存,用来储存程序和运行产生的数据。这段内存有起始地址和结束地址,比如从0x1000到0x8000,起始地址是较小的那个地址,结束地址是较大的那个地址

    程序运行过程中,对于动态的内存占用请求(比如新建对象,或者使用malloc命令),系统就会从预先分配好的那段内存之中,划出一部分给用户,具体规则是从起始地址开始划分(实际上,起始地址会有一段静态数据,这里忽略)。举例来说,用户要求得到10个字节内存,那么从起始地址0x1000开始给他分配,一直分配到地址0x100A,如果再要求得到22个字节,那么就分配到0x1020。

    这种因为用户主动请求而划分出来的内存区域,叫做 Heap(堆)。它由起始地址开始,从低位(地址)向高位(地址)增长。Heap 的一个重要特点就是不会自动消失,必须手动释放,或者由垃圾回收机制来回收。

    3、内存模型:Stack

    除了 Heap 以外,其他的内存占用叫做 Stack(栈)。简单说,Stack 是由于函数运行而临时占用的内存区域

    请看下面的例子。

    int main(){int a=2;int b=3;}

    上面代码中,系统开始执行main函数时,会为它在内存里面建立一个帧(frame),所有main的内部变量(比如a和b)都保存在这个帧里面。main函数执行结束后,该帧就会被回收,释放所有的内部变量,不再占用空间。

    如果函数内部调用了其他函数,会发生什么情况?

    int main(){int a=2;int b=3;return add_a_and_b(a,b);}

    上面代码中,main函数内部调用了add_a_and_b函数。执行到这一行的时候,系统也会为add_a_and_b新建一个帧,用来储存它的内部变量。也就是说,此时同时存在两个帧:main和add_a_and_b。一般来说,调用栈有多少层,就有多少帧。

    等到add_a_and_b运行结束,它的帧就会被回收,系统会回到函数main刚才中断执行的地方,继续往下执行。通过这种机制,就实现了函数的层层调用,并且每一层都能使用自己的本地变量。

    所有的帧都存放在 Stack,由于帧是一层层叠加的,所以 Stack 叫做栈。生成新的帧,叫做"入栈",英文是 push;栈的回收叫做"出栈",英文是 pop。Stack 的特点就是,最晚入栈的帧最早出栈(因为最内层的函数调用,最先结束运行),这就叫做"后进先出"的数据结构。每一次函数执行结束,就自动释放一个帧,所有函数执行结束,整个 Stack 就都释放了。

    Stack 是由内存区域的结束地址开始,从高位(地址)向低位(地址)分配。比如,内存区域的结束地址是0x8000,第一帧假定是16字节,那么下一次分配的地址就会从0x7FF0开始;第二帧假定需要64字节,那么地址就会移动到0x7FB0。

    汇编语言保留字

    保留字(reserved words)有特殊意义并且只能在其正确的上下文中使用。默认情况下,保留字是没有大小写之分的。比如,MOV 与 mov、Mov 是相同的。

    保留字有不同的类型:

    • 指令助记符,如 MOV、ADD 和 MUL。
    • 寄存器名称。
    • 伪指令,告诉汇编器如何汇编程序。(不是机器指令)
    • 属性,提供变量和操作数的大小与使用信息。例如 BYTE 和 WORD。
    • 运算符,在常量表达式中使用。
    • 预定义符号,比如 @data,它在汇编时返回常量的整数值。

    下表是常用的保留字列表。

    $PARITY?DWORDSTDCALL
    ?PASCALFARSWORD
    @BQWORDFAR16SYSCALL
    @FREAL4FORTRANTBYTE
    ADDRREAL8FWORDVARARG
    BASICREAL10NEARWORD
    BYTESBYTENEAR16ZERO?
    CSDORDOVERFLOW? 
    CARRY?SIGN?  

    伪指令

    DW 定义字(2字节).

    PROC 定义过程.

    ENDP 过程结束.

    SEGMENT 定义段.

    ASSUME 建立段寄存器寻址.

    ENDS 段结束.

    END 程序结束.

    伪指令 (directive) 是嵌入源代码中的命令,由汇编器识别和执行。伪指令不在运行时执行,但是它们可以定义变量、宏和子程序;为内存段分配名称,执行许多其他与汇编器相关的日常任务。

    默认情况下,伪指令不区分大小写。例如,.data,.DATA 和 .Data 是相同的。

    下面的例子有助于说明伪指令和指令的区别。DWORD 伪指令告诉汇编器在程序中为一个双字变量保留空间。另一方面,MOV 指令在运行时执行,将 myVar 的内容复制到 EAX 寄存器中:

    myVar DWORD 26
    mov eax,myVar

    尽管 Intel 处理器所有的汇编器使用相同的指令集,但是通常它们有着不同的伪指令。比如,Microsoft 汇编器的 REPT 伪指令对其他一些汇编器就是无法识别的。

    定义段

    汇编器伪指令的一个重要功能是定义程序区段,也称为段 (segment)。程序中的段具有不同的作用。如下面的例子,一个段可以用于定义变量,并用 .DATA 伪指令进行标识:

    .data

    .CODE 伪指令标识的程序区段包含了可执行的指令:

    .code

    .STACK 伪指令标识的程序区段定义了运行时堆栈,并设置了其大小:

    .stack 100h

    指令

    指令(instruction)是一种语句,它在程序汇编编译时变得可执行。汇编器将指令翻译为机器语言字节,并且在运行时由 CPU 加载和执行。

    一条指令有四个组成部分:

    • 标号(可选)
    • 指令助记符(必需)
    • 操作数(通常是必需的)
    • 注释(可选)

    不同部分的位置安排如下所示:

    [label: ] mnemonic [operands] [;comment]

    现在分别了解每个部分,先从标号字段开始。

    1) 标号

    标号(label)是一种标识符,是指令和数据的位置标记。标号位于指令的前端,表示指令的地址。同样,标号也位于变量的前端,表示变量的地址。标号有两种类型:数据标号和代码标号。

    数据标号标识变量的位置,它提供了一种方便的手段在代码中引用该变量。比如,下面定义了一个名为 count 的变量:

    count DWORD 100

    汇编器为每个标号分配一个数字地址。可以在一个标号后面定义多个数据项。在下面的例子中,array 定义了第一个数字(1024)的位置,其他数字在内存中的位置紧随其后:

    array DWORD 1024, 2048
    DWORD 4096, 8192

    程序代码区(指令所在区段)的标号必须用冒号(:)结束。代码标号用作跳转和循环指令的目标。例如,下面的 JMP 指令创建一个循环,将程序控制传递给标号 target 标识的位置:

    target:
    mov ax,bx
    ...
    jmp target

    代码标号可以与指令在同一行上,也可以自己独立一行:

    L1: mov ax, bx
    L2 :

    标号命名规则要求,只要每个标号在其封闭子程序页中是唯一的,那么就可以多次使用相同的标号。

    2) 指令助记符

    指令助记符(instruction mnemonic)是标记一条指令的短单词。在英语中,助记符是帮助记忆的方法。相似地,汇编语言指令助记符,如 mov, add 和 sub,给出了指令执行操作类型的线索。下面是一些指令助记符的例子:

    助记符说明助记符说明
    MOV传送(分配)数值MUL两个数值相乘
    ADD两个数值相加JMP跳转到一个新位置
    SUB从一个数值中减去另一个数值CALL调用一个子程序

    3) 操作数

    操作数是指令输入输出的数值。汇编语言指令操作数的个数范围是 0〜3 个,每个操作数可以是寄存器、内存操作数、整数表达式和输入输岀端口。
    生成内存操作数有不同的方法,比如,使用变量名、带方括号的寄存器等。变量名暗示了变量地址,并指示计算机使用给定地址的内存内容。下表列出了一些操作数示例:

    示例操作数类型示例 操作数类型
    96 整数常量eax寄存器
    2+4整数表达式count内存

    现在来考虑一些包含不同个数操作数的汇编语言指令示例。比如,STC 指令没有操作数:

    stc ;进位标志位置 1

    INC 指令有一个操作数:

    inc eax ;EAX 加 1

    MOV 指令有两个操作数:

    mov count, ebx ;将 EBX 传送给变量 count

    操作数有固有顺序。当指令有多个操作数时,通常第一个操作数被称为目的操作数,第二个操作数被称为源操作数(source operand)。

    一般情况下,目的操作数的内容由指令修改。比如,在 mov 指令中,数据就是从源操作数复制到目的操作数。

    IMUL 指令有三个操作数,第一个是目的操作数,第二个和第三个是进行乘法的源操作数:

    imul eax,ebx,5

    在上例中,EBX 与 5 相乘,结果存放在 EAX 寄存器中。

    4) 注释

    注释是程序编写者与阅读者交流程序设计信息的重要途径。程序清单的开始部分通常包含如下信息:

    • 程序目标的说明
    • 程序创建者或修改者的名单
    • 程序创建和修改的日期
    • 程序实现技术的说明

    注释有两种指定方法:

    • 单行注释,用分号(;)开始。汇编器将忽略在同一行上分号之后的所有字符。
    • 块注释,用 COMMENT 伪指令和一个用户定义的符号开始。汇编器将忽略其后所有的文本行,直到相同的用户定义符号出现为止。

    示例如下:

    COMMENT !
    This line is a comment.
    This line is also a comment.
    !

    其他符号也可以使用,只要该符号不出现在注释行中:

    COMMENT &
    This line is a comment.
    This line is also a comment.
    &

    当然,程序员应该在整个程序中提供注释,尤其是代码意图不太明显的地方。

    5) NOP(空操作)指令

    最安全(也是最无用)的指令是 NOP(空操作)。它在程序空间中占有一个字节,但是不做任何操作。它有时被编译器和汇编器用于将代码对齐到有效的地址边界

    在下面的例子中,第一条指令 MOV 生成了 3 字节的机器代码。NOP 指令就把第三条指令的地址对齐到双字边界(4 的偶数倍)

    00000000 66 8B C3 mov ax,bx
    00000003 90 nop ;对齐下条指令
    00000004 8B D1 mov edx,ecx

    x86 处理器被设计为从双字的偶数倍地址处加载代码和数据,这使得加载速度更快。

    展开全文
  • 汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言...
  • 汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言
  • 汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言
  • 汇编语言 汇编语言 汇编语言 汇编语言 汇编语言
  • 汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言
  • 汇编语言学习汇编语言学习汇编语言学习汇编语言学习汇编语言学习汇编语言学习汇编语言学习汇编语言学习汇编语言学习汇编语言学习汇编语言学习汇编语言学习汇编语言学习
  • 汇编语言教案汇编语言教案汇编语言教案汇编语言教案汇编语言教案汇编语言教案汇编语言教案汇编语言教案
  • 汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言汇编语言
  • 汇编语言编程题总结(特别适用河北专接本)

    万次阅读 多人点赞 2021-05-10 15:45:54
    汇编语言的编程题 如有不足,还望大佬们指教 汇编语言基本框架(考试时,当你实在不会写的时候,把基本框架写上会有基本框架的分数) 注:汇编语言的注释是 ; 分号 其他语言一般是 // DATAS SEGMENT ;数据段 ;此处...

    专接本交流群:1051749714 (有什么问题欢迎进群讨论)
    汇编语言的编程题
    如有不足,还望大佬们指教

    汇编语言基本框架
    1 内存中交换两个数的位置
    2比较两个数的大小(求最大,求最小)
    3 计算A+B=C
    4求1-100的和,存入SUM单元
    5 求内存中正负零的个数
    6 求十个数的最大值
    7 统计键盘输入的大写字母的个数,回车符结束
    8 DOS功能调用的示例
    9 求1-100之间奇数的和
    10 求大小写转换
    11 把AL的值乘10(不用MUL)
    12 统计AL寄存器中1的个数(相当于AL里面数二进制中1的个数),并屏幕显示

    汇编语言基本框架(考试时,当你实在不会写的时候,把基本框架写上会有基本框架的分数)

    注:汇编语言的注释是 ; 分号 其他语言一般是 //

    DATAS SEGMENT	;数据段
        ;此处输入数据段代码  
    DATAS ENDS
     
    CODES SEGMENT	;代码段
        ASSUME CS:CODES,DS:DATAS		;数据段给DS,代码段给CS
    START:			;开始代码
        MOV AX,DATAS	;需要先把DATAAX寄存器,然后再从AXDSDATA不能直接给DS
        MOV DS,AX
        ;此处输入代码段代码
        MOV AH,4CH		;结束语句
        INT 21H
        
    CODES ENDS		;代码段结束
        END START	;结束代码
    

    1 内存中交换两个数的位置

    DATA SEGMENT 
    A DB 12H	;定义两个变量
    B DB 24H
    DATA ENDS 
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV AL,A	;A->AL
    	MOV BL,B	;B->BL
    	MOV A,BL	;BL->A
    	MOV B,AL	;AL->B
    	 
    	 
    EXIT:
        MOV AH,4CH
        INT 21H
    CODES ENDS
        END START
    

    2比较两个数的大小(求最大,求最小)

    DATA SEGMENT 
    A DB 12H	;定义两个变量
    B DB 24H
    DATA ENDS 
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    				;A里面放最大值,B里面放最小值
    	MOV AL,A	;A->AL
    	CMP AL,B	;比较AB的大小
    	JG EXIT		;如果A大于B,就跳转到EXIT
    	MOV BL,B	;如果A小于B,就交换AB的位置
    	MOV A,BL
    	MOV B,AL
    	
    	
    	 
    EXIT:
        MOV AH,4CH
        INT 21H
    CODES ENDS
        END START
    

    3 计算A+B=C

    DATA SEGMENT 
    A DB 12H	;定义三个变量
    B DB 24H
    C DB 0
    DATA ENDS 
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV AL,A	;A放入AL
    	ADD AL,B	;AL+B (结果是默认放入AL)
    	MOV C,AL	;AL放入C
    	
     
    	 
    EXIT:
       		MOV AH,4CH
            INT 21H
    CODES ENDS
        END START
    

    4求1-100的和,存入SUM单元

    DATA SEGMENT 
    SUM DW 0	;这里就把SUM定义成字类型,字节类型放不开
    DATA ENDS 
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV AX,0	;AX当作和存放的地方,先把AX0
    	MOV BX,1	;BX当作每次加的数
    	MOV CX,100	;CX当作循环次数
    	
    LOP:
    	ADD AX,BX	;BXAX放到AX当中
    	INC BX		;BX每次加1
    	LOOP LOP	;循环LOPLOP的循环次数由CX决定
    	
    	MOV SUM,AX	;
    	
    	 
    EXIT:
       		MOV AH,4CH
            INT 21H
    CODES ENDS
        END START
    

    5 求内存中正负零的个数

    DATA SEGMENT 
    BUF DB 2,-5,6,-8,0,0,1,-9,5,4	;定义了十个变量
    PLUS DB 0		;存放正负零的个数
    MINUS DB 0
    ZERO DB 0
    DATA ENDS 
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV BX, OFFSET BUF	;BUF变量的偏移地址放到BX
    	MOV CX,10			;循环10次,
    	
    LOP:
    	MOV AL,[BX]		;把偏移地址为BX的变量放到AL
    	CMP AL,0		;0比较
    	JGE LOP1		;大于等于的时候跳转到LOP1
    	INC MINUS		;小于的时候就是负数了,MINUX加一
    	JMP LOP3		;跳转到LOP3
    LOP1:
    	CMP AL,0		;大于0就跳转到LOP2
    	JG LOP2
    	INC ZERO		;等于0就是0了,ZERO1
    	JMP LOP3		;跳转到LOP3
    LOP2:
    	INC PLUS		;正数+1
    LOP3:
    	LOOP LOP		;继续循环
    	
    	 
    EXIT:
       		MOV AH,4CH
            INT 21H
    CODES ENDS
        END START
    

    6 求十个数的最大值

    DATA SEGMENT 
    	BUF DB 2,-5,6,-8,0,0,1,-9,5,4	;定义了十个变量
    DATA ENDS 
    
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV BX, OFFSET BUF	;BUF变量的偏移地址放到BX
    	MOV CX,9			;循环9次,因为把第一个值放到AL
    	
    	MOV AL,[BX]
    	INC BX
    	
    	
    LOP:
    	CMP AL,[BX]		;ALBUF里面的值比较
    	JG LOP2			;AL大的话,就直接跳过
    	MOV AL,[BX]		;AL小,就把当前的值给AL
    	
    LOP2:
    	INC BX			;每次都把BX+1,用来取下一个数
    	LOOP LOP		;继续循环
    	
    	 
    EXIT:
       		MOV AH,4CH
            INT 21H
    CODES ENDS
        END START
    

    7 统计键盘输入的大写字母的个数,回车符结束

    DATA SEGMENT 
    	 
    DATA ENDS 
    
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV CL,0	;CL保存大写字母的个数
    	
    LOP:
    	MOV AH,01H	;cmd键盘输入字符固定格式
    	INT 21H
    	
    	CMP AL,0DH	;匹配是不是回车 回车的值是ODH
    	JZ EXIT		;如果是回车,就直接退出
    	
    	CMP AL,'A'	;如果小于A,就下一次循环
    	JL LOP2
    	
    	CMP AL,'Z'	;大于Z就下一次循环
    	JG LOP2
    	
    	INC CL		;如果大写字母就把CL+1
    	
    LOP2:
    	LOOP LOP	;继续循环
    	
    	 
    	 
    EXIT:
       		MOV AH,4CH
            INT 21H
    CODES ENDS
        END START
    

    8 DOS功能调用的示例

    字符输入输出
    
    DATA SEGMENT 
    	 
    DATA ENDS 
    
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV AH,01H	 ;键盘输入的时候,给AH  1
    	INT 21H		 ;然后INT 21H调用,默认输入到ALMOV DL,AL	 ;CMD窗口输出的时候,要把输出的放到DLMOV AH,02H	 ;AH  2
    	INT 21H
    	
    	 
    	 
    EXIT:
       		MOV AH,4CH
            INT 21H
    CODES ENDS
        END START
    
    字符串输入输出
    
    DATA SEGMENT 
    	 BUF DB 20 DUP('$')
    	 BUFF DB 'Hello World!$'
    DATA ENDS 
    
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV DX,OFFSET BUF	;把偏移地址给DX,也可以用 LEA DX,BUF  二者皆可
    	MOV AH,0AH	 ;键盘输入的时候,给AH  10
    	INT 21H		 ;然后INT 21H调用,默认输入到BUFMOV DX,OFFSET BUFF	 ;CMD窗口输出的时候,要把输出偏移地址放到DXMOV AH,09H	 ;AH  2
    	INT 21H
    	
    	 
    	 
    EXIT:
       		MOV AH,4CH
            INT 21H
    CODES ENDS
        END START
    

    9 求1-100之间奇数的和

    DATA SEGMENT 
    DATA ENDS 
    
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV AX,0	;用来存奇数和
    	MOV BX,1	;用来当加的量
    	MOV CX,100	;用来控制循环次数
    	
    LOP:
    	TEST BX,01H	;如果是偶数,那么&1肯定是0,如果是奇数&11
    	JZ LOP2		;偶数就跳过
    	ADD AX,BX	;BX加到AX
    	
    
    LOP2:
    	INC BX		;BX每次加1
    	LOOP LOP	;循环
    	  
    EXIT:
       	MOV AH,4CH
        INT 21H
    CODES ENDS
        END START
    

    10 求大小写转换

    这里提供两种方法,A的ASCII的值是65,也就是41H   a的ASCII的值是97,也就是61H
    我们利用ASCII的差值之间,差20H 直接异或20H就可以 
    20H比较特殊,他是二进制0010 0000  直接异或就可以,这一位是0的话就变成1了,也就是加上20H了
    这一位是1的话,异或后就变成0了,也就是减去20H了
    
    DATA SEGMENT 
    	BUF DB 'A'
    DATA ENDS 
    
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV AL,BUF
    	XOR AL,20H
    	MOV BUF,AL
    	  
    EXIT:
       	MOV AH,4CH
        INT 21H
    CODES ENDS
        END START
    

    普通比较法

    DATA SEGMENT 
    	BUF DB 'A'
    DATA ENDS 
    
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV AL,BUF	
    	CMP AL,'a'	;比a大就跳转到LOP2
    	JGE LOP2
    	CMP AL,'A'	;看看是不是大于A小于Z
    	JL EXIT
    	CMP AL,'Z'
    	JG EXIT
    	ADD AL,20H	;是字母的话就加上20H
    	JMP EXIT
    	
    LOP2:
    	CMP AL,'z'	;看看是不是大于a小于z
    	JG EXIT
    	SUB AL,20H	;是字母就减去20H
    	  
    EXIT:
    	MOV BUF,AL
       	MOV AH,4CH
        INT 21H
    CODES ENDS
        END START
    

    11 把AL的值乘10(不用MUL)

    DATA SEGMENT
    
    DATA ENDS 
    
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV AL,1	;AL赋值1
    	SHL AL,1	;二进制左移一位,也就是乘2放进AL
    	MOV BL,AL	;AL放进BLMOV CL,2	;2放进CL,左移右移操作大于1位的都要放到CL里面
    	SHL AL,CL	;二进制左移两位,也就是AL左移了三位也就是乘8
    	ADD AL,BL	;再把BL加上AL也就是2倍加8倍。也就是乘10EXIT:
       	MOV AH,4CH
        INT 21H
    CODES ENDS
        END START
    

    12 统计AL寄存器中1的个数(相当于AL里面数二进制中1的个数),并屏幕显示

    DATA SEGMENT
    
    DATA ENDS 
    
    CODES SEGMENT 
    	ASSUME DS:DATA,CS:CODES
    START:
    	MOV AX,DATA
    	MOV DS,AX
    	
    	MOV AL,33H	;赋值
    	MOV BL,0	;BL用来记录1的个数
    	
    LOP:
    	TEST AL,01H	;看看最后一位是不是1,如果是1就计数
    	JZ LOP2		;不是1就跳转到LOP2
    	INC BL 
    LOP2:
    	SHR AL,1	;右移1位,如果这个数是0了,就退出
    	JZ EXIT		;右移,最后一位会去掉,最高位会补零
    	JMP LOP		;还有数的话,就继续循环
    	  
    EXIT:
    	MOV DL,BL	;BL计数的值放到DL,输出到屏幕
    	MOV AH,02H
    	INT 21H
    	
       	MOV AH,4CH
        INT 21H
    CODES ENDS
        END START
    
    展开全文
  • 汇编语言全接触 汇编语言详解 汇编语言 适合初学者
  • 汇编语言汇编语言汇编语言
  • 汇编语言王爽汇编语言王爽汇编语言王爽汇编语言王爽汇编语言王爽汇编语言王爽汇编语言王爽汇编语言王爽汇编语言王爽汇编语言王爽汇编语言王爽汇编语言王爽
  • 汇编语言 汇编语言

    2009-12-03 18:33:57
    汇编语言程序设计 汇编语言程序设计 汇编汇编语言程序设计 语言程序设计 汇编语言程序设计
  • ARM汇编语言教程ARM汇编语言教程ARARM汇编语言教程M汇编语言教程ARM汇编语言教程ARM汇编语言教程
  • 汇编语言_王爽汇编语言_王爽汇编语言_王爽汇编语言_王爽汇编语言_王爽
  • 汇编语言.rar 汇编语言.rar 汇编语言.rar 汇编语言.rar 汇编语言.rar

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 254,852
精华内容 101,940
关键字:

汇编语言