汇编语言实现多种进制的通用输入输出
作者:罗南超 向昌成 李唐辉
来源:《电脑知识与技术》2008年第36
        摘要:基于小模式,调用C语言的Scanf()Printf()函数实现了在汇编语言中不同进制的输入和输出,文章对在汇编程序中调用C函数的关键问题进行了分析并据此给出了在汇编语言中实现多种进制的通用输入输出源程序。
        关键词:汇编语言;小模式;调用C函数;多种进制;通用输入输出;源程序;实现
        中图分类号:TP312文献标识码:A文章编号:1009-3044(2008)36-3068-03
        Realization of Varied Hexadecimal Universal Input-output with the Assembly Language
        LUO Nan-chao1, XIANG Chang-cheng1,2, LI Tang-hui1,3
        (1. Aba Teachers College Department of Computer Science, Pixian 623000, China2. University of Electronic Science and Technology Institute of Applied Mathematics, Chengdu 610054, China3. Sichuan University School of Computer, Chengdu 610054, China)
        Abstract: Based on the small model, called the C language Scanf() and Printf() function to achieve in the compilation of language in different band of input and output, the article in the compilation process in the call C functions of the key issues were analyzed and, accordingly Language is given in the compilation of the band to achieve a variety of input and output common source.
        Key words: assembly languagethe small modelcalled C functionvaried Hexadecimaluniversal input-outputsource programrealization
        1 引言
        在汇编语言中要实现不同进制的输入输出一直比较麻烦,虽然有很多文章就这方面的问题做了深入细致地探讨[1-2]。但所有的方法都较为繁琐,程序长度较大,并且使用户在编写程序时往往为寻入口参数感到力不从心,因此必须寻求一种简单易行的方法,联想到在C语言中要实现各种进制的输入输出非常简单,何不利用在汇编语言中调用C语言的输入输出函数实现各种的进制的输入输出呢?下面就基于小模式下汇编语言如何调用C语言的Scanf()Printf()函数实现多种进制的通用输入输出进行分析并给出具体源程序。
        2 汇编语言程序调用C函数的关键
        结合汇编语言与C语言连接的关键问题[3]C语言与汇编语言混合编程的约定规则[4],总结得出汇编语言程序调用C函数的关键性问题:
        2.1 汇编程序与C程序的模块要正确连接
        必须做到两点:一是汇编模块必须采用和C模块一致的存储模式;二是汇编模块必须遵守和C兼容的命名约定,包括函数和变量命名约定。
        针对第一点,这里采用小模式(.model small)实现,在小模式下所有的指针都是Near型近指针,程序运行效率高。
        针对第二点,主要完成对汇编语言程序所调用的C语言函数、变量用关键字EXTERN进行说明,形式如下:
        EXTERN被调用函数名:函数属性
        EXTERN变量名:变量属性
        其中函数属性为near;变量属性可以为byteworddword等。
        例如在C语言程序中有如下说明:int i, array[10]; charch; long result;
        汇编语言程序中,应说明为:EXTERN i:word,arrray:word,ch:byte,result:dword
        此外,为了使C语言的标识符能在汇编语言中可见,必须用PUBLIC操作符定义它。
        2.2 参数的正确传递是关键
        汇编语言程序通过堆栈向C语言函数传递参数,在汇编语言中将BP作为基址寄存器,调用程序先将来自于C程序中的参数压人堆栈中(参数压入堆栈的顺序与实参表中参数的顺序相反),然后当需要使用这些参数时,再用BP加上不同的偏移量依次对堆栈中的数据进行存取操作。在汇编语言程序调用C函数完成后,立即平衡堆栈。即清除堆栈里的参数,恢复堆栈到调用前的情形。这里可以利用“add sp,imm”指令来完成,使SP的值增加一个指定的值。imm这个值应该是堆栈中返回地址所占字节数与传送参数所占用字节数之和。
        为便于讨论,下面以输入输出一个字为例,给出具体的输入输出源程序。printf函数是如何实现的
        3 具体编程实现
        3.1 十进制、八进制、十六进制的通用输入输出源程序
        .model small
        .data
        f21db 'Please input a data to A:',0;显示输入数据提示信息
        f22db '%d',0 ;若是八进制则改为%o,十六进制则改为%x
        f23db 'output data is:',0;显示输出二进制数据提示信息
        f24db '%d',0;若是八进制则改为%o,十六进制则改为%x
        A dw 0;输入的数据放入A存储单元
        .code
        EXTRN _printf:NEAR
        EXTRN _scanf:NEAR
        PUBLIC _main
        _main proc near
        start:
        mov ax,@data
        mov ds,ax
        mov ax,offset f21
        push ax
        call near ptr _printf
        pop cx
        lea ax,A
        push ax
        mov ax,offset f22
        push ax
        call near ptr _scanf ;输入一个字长度的十进制数
        add sp,4
        mov ax,offset f23
        push ax
        call near ptr _printf
        pop cx
        push A
        lea ax,f24
        push ax
        call near ptr _printf ;输出十进制数
        add sp,4
        ret
        _main endp
        end start
        3.2 二进制的通用输入输出源程序
        由于C语言中没有提供直接输入输出二进制的方法,这儿利用DOS中断调用1号、2号功能分别实现二进制的输入输出,具体源程序如下:
        .model small
        .data
        f21 db 'Please input a data to A:',0; 显示输入二进制数据提示信息
       
        f23 db 'output Binary data is:',0 ; 显示输出二进制数据提示信息
        A DB 15 DUP(0);定义一个字长度的存储单元用于存储输入的二进制数
        .code
        EXTRN _printf:NEAR
        PUBLIC _main
        _main proc near
        start:
        mov ax,@data
        mov ds,ax
        mov ax,offset f21
        push ax
        call near ptr _printf
        pop cx
        xor si,si
        next:mov ah,1 ;输入16位二进制数
        int 21h
        mov a[si],al
        inc si
        cmp si,15
        jle next
        mov dl,13;回车
        mov ah,2
        int 21h
        mov dl,10;换行
        mov ah,2
        int 21h
        mov ax,offset f23; 输出16位二进制数
        push ax
        call near ptr _printf
        pop cx
        xor si,si
        next1:mov dl,A[si]
        mov ah,2
        int 21h
        inc si
        cmp si,15
        jle next1
        mov ah,1;屏幕回显结果
        int 21h
        ret
        _main endp
        end start
        4 程序验证