汇编语言学习12:模块化程序设计

        随着汇编程序的进一步复杂化,我们可以将多个汇编文件一起汇编,每个文件称作一个模块,并且在不同的模块之间交换数据,以在实现更加庞大和复杂的功能同时依然保持可读性。

        另外,输入/输出是程序最重要的部分之一。在之前我们已经学习了一小部分通过DOS中断实现标准I/O的指令。经过高级语言特性的进一步拓展,汇编语言可以实现更加复杂的I/O。

目录

模块化程序设计

源程序文件的包含

子程序库的调入

总结


模块化程序设计

源程序文件的包含

MASM汇编程序允许把源程序放在几个不同的文本文件中,在汇编时通过包含伪指令INCLUDE结合成一体。即:

include 文件名

文件名必须符合DOS命名规范。对于文件的后缀没有明确规定,但一般默认为ASM,MAC(宏定义库)或INC(包含文件)。文件名可以包含路径。当没有指定路径时,MASM会在以下三个路径查找:

  • 命令行参数/I指定的目录下查找
  • 当前文件所在的目录下查找
  • 环境参数INCLUDE指定的目录下查找

INCLUDE伪指令进行汇编时,会将它指定的文本文件内容插入到伪指令所在的位置进行同时汇编。

下面给出一个多模块同时汇编的例子:将输入的数据按照升序输出。最多输入100个数据,每个数据都是无符号字节常量。

分析:常见的DOS输出应该汇编为宏,保存在宏定义库中,方便其他文件共享。另外设计处理数据输入和输出的子程序保存在源文件文件中。主程序则主要提供入口参数和出口参数。

; 宏定义库 MACRO.mac
dispchar macro char
    mov dl,char
    mov ah,2
    int 21h
    endm
dispmsg macro msg
    mov dx,offset msg
    mov ah,9 
    int 21h
endm
; 主程序文件
include MACRO.mac
.model small
.stack
.data
msg1 db 'Please enter the number(XX):',13,10,'$'
msg2 db 'The number sentered are:',13,10,'$'
msg3 db 'The sorting result(ascending):',13,10,'$'
crlf db 13,10,'$'
maxcount = 100
count dw ?
buf db maxcount dup(?)
.code
.startup
dispmsg msg1
mov bx,offset buf
call input
.if cx!=0
mov count,cx
dispmsg crlf
dispmsg msg2
mov bx,offset buf
mov cx,count
start2:mov al,[bx]
    call aldisp
    disp char','
    inc bx
    loop start2
    dispmsg crlf
    mov bx offset buf
mov cx,cunt
call sorting
dispmsg msg3
mov bx,offset buf
mov cx,count
start3: mov al,[bx]
call aldisp
disp char','
inc bx
loop start3
dispmsg crlf
.endif
start4: .exit 0
include minproc.asm
    end

;minproc.asm子程序实现文件
aldisp proc
    push ax
    push dx
    push ax
    mov dl,al
    shr dl,1
    shr dl,1
    shr dl,1
    shr dl,1
    or dl,30h
    cmp dl,39h
    jbe aldisp1
    add dl,7
aldisp1:mov ah,2
    int 21h
    pop dx
    and dl,0fh
    or dl,30h
    cmp dl,39h
    jbe aldisp2
    add dl,7
aldisp2:
    mov ah,2
    int 21h
    pop dx
    pop ax
    ret
aldisp endp
sorting proc
    .if cx!=0
    .if cx!=1
    push ax
    push dx
    push si
    push si,bx
    dec cx
outlp:mov dx,cx
    mov bx,si
inlp:mov al,[bx]
    cmp al,[bx+1]
    jna next
    xchg al,[bx+1]
    mov [bx],al
next:inc bx
    dec dx
    jnz inlp
    loop outlp
    pop si
    pop dx
    pop ax
    .endif
    .endif
sortend:ret
sorting endp

convert macro
    local input21,input22
    local input24,input25
    cmp dl,0
    je input25
    .if dl>9
    sub dl,7
    .endif
input21:and dl,0fh
    .if dh!=0
    .if dh>9
    sub dh,7
    .endif
input22:shl dh,1
    shl dh,1
    shl dh,1
    shl dh,1
    or dl,dh
input24:mov [bx],dl
    inc bx
    inc cx
input25: 
    endm

input proc
    push ax
    push dx
    xor cx,cx
input01:xor dx,dx
input02:mov ah,1
    int 21h
input10:cmp al,0dh
    je input30
    cmp al,' '
    je input20
    cmp al,','
    je input20
    cmp al,8
    je input17
    cmp al,'0'
    jb input17
    cmp al,'f'
    ja input17
    cmp al,'a'
    jb input11
    sub al,20h
    jmp input12
input11:cmp al,'f'
    ja input17
    cmp al,'a'
    ja input12
    cmp al,'9'
    ja input17
input12:
    cmp dl,0
    jne input13
    mov dl,al
    jmp input02
input13:
    cmp dh,0
    jne input17
    mov dh,dl
    mov dl,al
    jmp input02
input17:
    mov dl,7
    mov ah,2
    int 21h
    mov dl,'?'
    mov ah,2
    int 21h
    jmp input01
input20:
    convert
    pop dx
    pop ax
    ret 
input endp

利用目标文件的连接开发源程序,需要注意几个问题。

  1. 全局变量要使用PUBLIC或者EXTERN声明
  2. 设置好段属性
  3. 正确处理参数传递问题。少量参数传递可以使用寄存器和堆栈传参。大量变量可以使用缓冲区buffer传参。也可以利用全局变量传递参数。
  4. 必须有且只有一个模块中还有主程序(用.STARTUP和.EXIT标注),其他模块为宏定义或者子程序形式。

子程序库的调入

当使用INCLUDE伪指令时,被调用的子程序.asm文件的所有代码(即便没有被使用)也会被一起汇编,最终造成可执行文件过于庞大。MASM汇编程序提供子程序库(.lib)的方法来克服这个缺点。

子程序库的调用相比源文件的调用更加严格。主要体现在:

  • 各子程序的传递参数方法需要保持一致
  • 子程序类型最好一样(都为FAR或者NEAR)
  • 采用相同的存储模式(寄存器或者堆栈)

可以编写完.asm文件后使用指令把子程序目标模块连接成一个库文件:

lib 库文件名(+源文件名)

当汇编成文件时,要使得子程序的类型一致,因此上面的例子如果要使用库管理,需要删除PUBLIC COUNT语句,并且所有的子程序都改为了NEAR类型(因为使用寄存器传参)。当使用LIB指令连接源文件时,注意连接的是汇编完成的.OBJ文件。

当连接完子程序库之后,就可以在主程序中使用INCLUDE LIB伪指令,这样就不需要在LINK时说明库文件。

总结

汇编语言的INCLUDE语句允许将多份源文件一起进行联合汇编与连接,而库文件管理程序减少了部分的汇编开销,可以使得其在需要时方便调用,提高了效率。

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值