前言
写汇编程序,如果只用一个.asm来做,维护不方便,程序的逻辑被工具函数淹没了.
可以分成多个.asm, 在主asm中include工具函数库的.inc
主程序
;////////////////////////////////////////////////////////////
; hw1j.asm
include helper.inc
;////////////////////////////////////////////////////////////
MYSEG_STACK segment stack
db 1000h dup (0)
MYSEG_STACK ends
;////////////////////////////////////////////////////////////
MYSEG_DATA segment PARA public "data"
STR_TITLE db '<>', 0dh, 0ah, 24h
STR_OVER db 'task over', 0dh, 0ah, 24h
TAB_LETTER_REPLACE db 0eeh ; '0'
db 081h ; '1'
db 07fh ; '2'
db 098h ; '3'
db 065h ; '4'
db 0a7h ; '5'
db 0c3h ; '6'
db 0e2h ; '7'
db 0f6h ; '8'
db 084h ; '9'
MYSEG_DATA ends
;////////////////////////////////////////////////////////////
MYSEG_CODE segment PARA public 'code'
assume cs:MYSEG_CODE, ds:MYSEG_DATA, ss:MYSEG_STACK
MAIN:
; 必须重新赋值数据段寄存器
mov ax, MYSEG_DATA
mov ds, ax
mov es, ax
; 打印标题
mov bx, offset STR_TITLE
push bx
call fnPrintString
; 执行任务
call fnDoTask_control_cmd
;////////////////////////////////////////////////////////////
;// 运行结果
;////////////////////////////////////////////////////////////
;////////////////////////////////////////////////////////////
; 退出程序
call fnExit
ret
;////////////////////////////////////////////////////////////
;// 函数 - 执行任务
;////////////////////////////////////////////////////////////
fnDoTask_control_cmd:
push bp
mov bp, sp
push sp
push dx
push ax
push bx
push cx
push si
; 输入数据, 将数字字符用字符替换表进行替换, 实现简单加密
mov al, '9'
push ax
call fnPrintHexByte
mov bx, offset STR_ENTER_KEY
push bx
call fnPrintString
fnDoTask_control_cmd_switch:
; 校验输入字符为 '0' ~ '9' 之间
cmp al, '0'
js fnDoTask_control_cmd_switch_end
cmp al, '9'
js fnDoTask_control_cmd_switch_is_0_9
jnz fnDoTask_control_cmd_switch_end
fnDoTask_control_cmd_switch_is_0_9:
;将字符变成数字
sub al, '0'
mov bx, offset TAB_LETTER_REPLACE
xor ah, ah
mov si, ax
mov al, [bx + si]
push ax
call fnPrintHexByte
mov bx, offset STR_ENTER_KEY
push bx
call fnPrintString
fnDoTask_control_cmd_switch_end:
pop si
pop cx
pop bx
pop cx
pop dx
pop sp
pop bp
ret
;////////////////////////////////////////////////////////////
MYSEG_CODE ends
end MAIN
子函数库头文件
; helper.inc
; imp on helper.asm
extern STR_EQU:BYTE
extern STR_ENTER_KEY:BYTE
extern CHAR_1:BYTE
extern CHAR_0:BYTE
extern fnExit:near
extern fnHalfCharAsBinaryData:near
extern fnCharAsBinaryData:near
extern fnPrintString:near
extern fnPrintChar:near
extern fnPrintBufferAsHexByte:near
extern fnPrintHexByte:near
extern fn_memset:near
extern fn_memmove:near
extern fn_memcpy:near
extern fn_memcmp:near
extern fn_memchr:near
子函数库实现文件
; helper.asm
public STR_EQU
public STR_ENTER_KEY
public CHAR_1
public CHAR_0
public fnExit
public fnPrintString
public fnPrintChar
public fnHalfCharAsBinaryData
public fnPrintHexByte
public fnCharAsBinaryData
public fn_memset
public fnPrintBufferAsHexByte
public fn_memcpy
public fn_memmove
public fn_memcmp
public fn_memchr
MYSEG_DATA segment PARA public "data"
STR_EQU db ' = ', 24h
STR_ENTER_KEY db 0dh, 0ah, 24h
CHAR_1 db '1'
CHAR_0 db '0'
MYSEG_DATA ends
MYSEG_CODE segment PARA public 'code'
assume cs:MYSEG_CODE, ds:MYSEG_DATA
;
;
;
;
;
;
;
;
;
;
;
;
fn_memchr:
push bp
mov bp, sp
push sp
push dx
push cx
push si
push di
; 取出参数
; 参数1 [bp + 4]
; 参数2 [bp + 6]
; 参数3 [bp + 8]
cld
xor ax, ax
mov si, [bp + 4] ; buf
mov dx, [bp + 6] ; c
mov cx, [bp + 8] ; count
fn_memchr_find_next:
cmp [si], dl
jnz fn_memchr_continue
jmp fn_memchr_end
fn_memchr_continue:
inc si
inc ax
loop fn_memchr_find_next
; can't find
mov ax, -1
fn_memchr_end:
pop di
pop si
pop cx
pop dx
pop sp
pop bp
ret 6 ; 栈平衡, 3个word
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
fn_memcmp:
push bp
mov bp, sp
push sp
push dx
push cx
push si
push di
; 取出参数
; 参数1 [bp + 4]
; 参数2 [bp + 6]
; 参数3 [bp + 8]
cld
mov di, [bp + 4]
mov si, [bp + 6]
mov cx, [bp + 8]
repz cmpsb
jnz fn_memcmp_is_less
mov ax, 0
jmp fn_memcmp_end
fn_memcmp_is_less:
jnc fn_memcmp_is_greate
mov ax, -1
jmp fn_memcmp_end
fn_memcmp_is_greate:
mov ax, 1
fn_memcmp_end:
pop di
pop si
pop cx
pop dx
pop sp
pop bp
ret 6 ; 栈平衡, 3个word
;
;
;
;
;
;
;
;
;
;
;
;
;
fn_memcpy:
fn_memmove:
push bp
mov bp, sp
push sp
push dx
push cx
push ax
push si
push di
; 取出参数
; 参数1 [bp + 4]
; 参数2 [bp + 6]
; 参数3 [bp + 8]
cld
mov di, [bp + 4]
mov si, [bp + 6]
mov cx, [bp + 8]
rep movsb
pop di
pop si
pop ax
pop cx
pop dx
pop sp
pop bp
ret 6 ; 栈平衡, 3个word
;
;
;
;
;
;
;
;
;
;
;
;
fn_memset:
push bp
mov bp, sp
push sp
push dx
push cx
push ax
; 取出参数
; 参数1 [bp + 4]
; 参数2 [bp + 6]
; 参数3 [bp + 8]
cld
mov cx, [bp + 8]
mov ax, [bp + 6]
mov di, [bp + 4]
rep stosb
pop ax
pop cx
pop dx
pop sp
pop bp
ret 6 ; 栈平衡, 3个word
;
fnCharAsBinaryData:
push bp
mov bp, sp
push sp
push dx
push cx
mov cx, 8
fnCharAsBinaryData_RCL:
RCL dl, 1
jnc fnCharAsBinaryData_RCL_is_0
mov al, CHAR_1
jmp fnCharAsBinaryData_RCL_loop
fnCharAsBinaryData_RCL_is_0:
mov al, CHAR_0
fnCharAsBinaryData_RCL_loop:
push ax
call fnPrintChar
loop fnCharAsBinaryData_RCL
pop cx
pop dx
pop sp
pop bp
ret 2
;
;
;
;
;
;
;
;
;
;
fnPrintBufferAsHexByte:
push bp
mov bp, sp
push sp
push dx
push si
push cx
push ax
; 取出参数
mov si, [bp + 4]
mov cx, [bp + 6]
fnPrintBufferAsHexByte_next:
mov ax, [si]
push ax
call fnPrintHexByte
inc si
loop fnPrintBufferAsHexByte_next
pop ax
pop cx
pop si
pop dx
pop sp
pop bp
ret 4
;
;
;
;
fnPrintHexByte:
push bp
mov bp, sp
push sp
push dx
push ax
push cx
; 取出参数
mov dx, [bp + 4]
; 显示字节的高4位为16进制字符
mov ax, dx
mov cl, 4
shr ax, cl
and ax, 0fh
push ax
call fnHalfCharAsBinaryData
; 显示字节的低4位为16进制字符
mov ax, dx
and ax, 0fh
push ax
call fnHalfCharAsBinaryData
pop cx
pop ax
pop dx
pop sp
pop bp
ret 2
;
fnHalfCharAsBinaryData:
push bp
mov bp, sp
push sp
push ax
mov ax, [bp + 4]
cmp al, 9
jc fnHalfCharAsBinaryData_0_9
jnz fnHalfCharAsBinaryData_a_f
fnHalfCharAsBinaryData_0_9:
; 0 ~ 9
add al, '0'
jmp fnHalfCharAsBinaryData_show
fnHalfCharAsBinaryData_a_f:
sub al, 0ah
add al, 'A'
fnHalfCharAsBinaryData_show:
push ax
call fnPrintChar
pop ax
pop sp
pop bp
ret 2
;
;
;
;
fnPrintChar:
push bp
mov bp, sp
push sp
push dx
push ax
mov dx, [bp + 4]
mov ah, 2
int 21h
pop ax
pop dx
pop sp
pop bp
ret 2
;
;
;
;
;
;
fnExit:
mov ax, 4c00h
int 21h
ret
;
;
;
;
;
;
;
;
fnPrintString:
push bp
mov bp, sp
push sp
push dx
push ax
mov dx, [bp + 4]
mov ah, 9
int 21h
pop ax
pop dx
pop sp
pop bp
ret 2
MYSEG_CODE ends
END
编译脚本
rem hw1j.cmd
del *.obj
del *.exe
ml16 /c hw1j.asm
ml16 /c helper.asm
link16 hw1j.obj helper.obj
debug hw1j.exe
rem hw1j.exe
pause
call cmd
运行结果