纯汇编中的头文件包含

前言

写汇编程序,如果只用一个.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 '<<switch test>>', 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
;// 功能 - void *memchr( const void *buf, int c, size_t count );
;// 调用示例
;// mov ax, 4
;// push ax
;// mov ax, 55h
;// push ax
;// mov ax, offset BUFDST ; dest buffer
;// push ax
;// call fn_memchr
;
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_memmove
;// 功能 - int *memcmp( void *dest, const void *src, size_t count );
;// ax < 0, dest < Src
;// ax == 0, dest == Src
;// ax > 0, dest > Src
;// 调用示例
;// mov ax, 4
;// push ax
;// mov ax, offset BUFSRC ; dest buffer
;// push ax
;// mov ax, offset BUFDST ; dest buffer
;// push ax
;// call fn_memcmp
;
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_memmove
;// 功能 - void *memmove( void *dest, const void *src, size_t count );
;// 备注 - fn_memcpy 和 fn_memmove 是一个实现, 在MFC中 memcpy 和 memmove 也是一个实现
;// 调用示例
;// mov ax, 4
;// push ax
;// mov ax, offset BUFSRC ; dest buffer
;// push ax
;// mov ax, offset BUFDST ; dest buffer
;// push ax
;// call fn_memmove
;
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
;// 功能 - void *memset( void *dest, int c, size_t count );
;// 调用示例
;// mov ax, 4 ; count
;// push ax
;// mov al, 0h ; char to set
;// push ax
;// mov ax, offset BufDst ; dest buffer
;// push ax
;// call fn_memset
;
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

;
;// 函数 - 按照16进制字节打印缓冲区
;// 参数 - fnPrintBufferAsHexByte(char* dest, WORD len)
;// 调用示例
;// mov ax, 4
;// push ax
;// mov ax, offset BUF_TO_PRT
;// push ax
;// call fnPrintBufferAsHexByte
;
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

;
;// 函数 - 打印16进制字节
;// 参数 - 入栈的16进制数据
;
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

;
;// 函数 - 退出程序
;// 参数 - 无
;// 调用示例
;// call fnExit
;
fnExit:
    mov ax, 4c00h
    int 21h
    ret

;
;// 函数 - 打印字符串
;// 参数 - 入栈的字符串地址
;// 调用示例
;// mov bx, offset STR_TITLE
;// push bx
;// call fnPrintString
;
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

运行结果

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值