1、第四章 汇编语言程序设计汇编语言的指令和机器语言的指令之间有一一对应的关系,是面向机器的语言,CPU 不同的机器有不同的汇编语言。汇编语言可以对输入输出端口直接调用,实时性能好,程序效率高、节省内存、运行速度快。1 汇编语言的格式8086汇编的一个语句行由 4个部分组成:标号、操作码、操作数和注释。各部分之间至少要用一个空格作为间隔。一个语句可以有后续行,规定以字符 定义一个字节Y DB 42H, 43H ; 定义两个字节Z DB 100DUP(?) ; 保留 100个字节 DW:定义字X DW 4142H ; 定义一个字Y DW 4243H, 4344H ; 定义两个字Z DW 10DUP(
2、0) ; 保留 10个字 DD:定义双字X DD ? ; 保留一个双字 段定义语句段定义的主要命令有 SEGMENT、ENDS、ASSUME 和 ORG。SEGMENT和 ENDS语句汇编语言程序分成段,在这些存储器段中,存放相应段的目标码。汇编程序必须知道程序的段结构,并知道在各种指令执行时将访问哪一个段,这些信息将由 ASSUME语句提供。语句 ORG,规定了段内的起始地址。一般来说,存储器段的具体位置由汇编程序来选择,也可根据汇编指令来提出要求: 不要搭接,段中的第一个可用字节是在 16字节界限上MY_SEG SEGMENT PARA ; PARA 可缺省MY_SEG ENDS 允许搭接
3、,但第一个可用字节必须是字的界限上MY_SEG SEGMENT WORDMY_SEG ENDS 段开始在指定的 16字节界限上,但第一个可用字节在指定的偏移位置上MY_SEG SEGMENT AT 1A2BH ; 段地址为 1A2BHORG 0003H ; 段内从偏移量 0003H开始MY_SEG ENDS 过程定义语句过程是程序的一部分,它们可被程序调用。每次可调用一个过程。当过程中的指令执行完后,控制返回调用它的地方。过程定义的主要命令有 PROC、ENDP、NEAR 和 FAR。PROC和 ENDP语句限定了一个过程,在定义时要指定是 NEAR还是FAR,缺省情况下是 NEAR。程序调用
4、是用指令 CALL,过程返回是用指令 RET。PRO_NAME PROCRETPRO_NAME ENDP 结束语句END语句,它标志着整个源程序的结束,它告诉汇编程序,没有更多的指令要汇编了。START: END START程序将从标号 START处开始执行。4 指令语句 指令助记符 NOP汇编程序将产生一字节指令,它使寄存器 AX的内容自行交换。NOP可以保留一些单元为以后填入指令用。 保留空格 NIUNIU在汇编程序中是为标号保留空格的,并不产生任何执行指令。 指令前缀 段超越 重复 锁定 操作数寻址方式 立即 寄存器 直接 通过基址寄存器间接 通过变址寄存器间接 通过基址寄存器加变址寄存
5、器间接 通过基址或变址寄存器加位移量间接 通过基址寄存器加变址寄存器加位移量间接 串操作指令汇编程序通过一个操作数自己的说明,来确定一个操作数的类型,从而帮助汇编程序确定当访问此操作时应产生什么样的代码。5 汇编语言程序设计 串操作sseg segment para stack stackdb 100 dup(0)sseg endsdseg segment parastri1 db 1752stri2 db 3814count equ $-stri2dseg endscode segmentassume cs:code, ds:dseg, es:dseg, ss:ssegmain proc f
6、arpush dsxor ax, axpush axmov ax, dsegmov ds, axmov es, axclccldmov si, offset stri1mov di, offset stri2mov cx, countcycle: lods stri1adc al, diaaastos stri2loop cycleretmain endpcode endsend main程序的功能是将两个用 ASCII码表示的 4位十进制数相加:2571+4183,原程序中十进制数的个位定位在最左边。如将个位定位在最右边,则要进行运算:1752+3814,应该将程序中的 CLD指令改成 ST
7、D指令,同时 SI和 DI的初始值应分别加上(COUNT-1)。 加法程序sseg segment para stack stackdb 256 dup(0)sseg endsdseg segment parax dd 12345678hy dd 87654321hz dd ?dseg endscode segmentassume cs:code, ds:dseg, es:dseg, ss:ssegmain proc farpush dsxor ax, axpush axmov ax, dsegmov ds, axmov si, offset xlea di, zmov ax, siadd a
8、x, si + 4mov di, axinc diinc diinc siinc simov ax, siadc ax, si + 4mov di, axretmain endpcode endsend main 两个 32位无符号数相乘0四 字15631 0双 字15低 字 B631高 字 A 0双 字15低 字 D631高 字 CAC B DC BA D4763 排序程序将数据表中的无符号数从小到大进行排序 C语言void main()unsigned int len = 16;unsigned int table = 200, 300, 400, 10, 20, 0,1, 8, 0x41
9、, 0x40, 0x42,50, 60, 0xffff, 2, 3 ;unsigned int temp, flag, i;doflag = 1;for (i=0; i tablei+1)temp = tablei;tablei = tablei+1;tablei+1 = temp;flag = 0; while(flag = 0); FORTRAN语言program mainimplicit noneinteger : len = 16integer : table(16)data table /200, 300, 400, 10, 20, 0, 1, 8, 0000 0000 0000 1
10、000mov bx, axmov cl, 02hshl ax, cl ; 0000 0000 0010 0000add ax, bx ; 0000 0000 0010 1000shl ax, cl ; 0000 0000 1010 0000mov y, axretmain endpcode endsend main 用子程序实现:十进制显示存储器中的无符号整数(字)sseg segment para stack stackdb 256 dup(0)sseg endsdseg segment paralen dw 16table dw 200, 300, 400, 10, 20, 0, 1, 8
11、dw 41h, 40h, 42h, 50, 60, 0ffffh, 2, 3dseg endscode segmentassume cs:code, ds:dseg, es:dseg, ss:ssegmain proc farpush dsxor ax, axpush axmov ax, dsegmov ds, axloop1: mov bx, 1mov cx, lendec cxmov si, offset tableloop2: mov ax, sicmp ax, si + 2jbe contxchg ax, si + 2mov si, axmov bx, 0cont: add si, 2
12、loop loop2cmp bx, 1jnz loop1; 输出排序结果mov cx, lendec cxmov si, offset tableloop3: mov ax, sipush axcall xyzadd si, 2mov dl, ,mov ah, 2int 21hloop loop3mov ax, sipush axcall xyzretmain endpxyz proc nearjmp m db ?x dw ?y dw ?: push bpmov bp, sppush axpush bxpush cxpush dxmov x, 10000mov y, 10mov m, 0mov
13、 bx, bp + 4cmp bx, 0jnz 0mov dl, 30hmov ah, 2int 21hjmp 30: mov ch, 54: mov ax, bxmov dx, 0div xmov bx, dxcmp m, 0jnz 1cmp al, 0jz 2mov m, 11: add al, 30hmov dl, almov ah, 2int 21h2: mov ax, xmov dx, 0div ymov x, axdec chjnz 43: pop dxpop cxpop bxpop axpop bpret 2xyz endpcode endsend main运行结果:0,1,2,3,8,10,20,50,60,64,65,66,200,300,400,65535