回 帖 发 新 帖 刷新版面

主题:C语言爱好者教我呀!

怎么实现从键盘输入十进制然后转换为二进制并显示出来啊!
转换的子程序我弄出来了
可是怎么实现键盘输入和把转换后的二进制显示出来呀
帮帮我呀
谢谢了!

回复列表 (共4个回复)

沙发

q 我在苦苦等待!!!

板凳

我来发一个我自己写的一些宏给你,本来想整理一下再发的.
因为有些指令是80386+指令,所以,你的程序开头要加.386P伪指令,这个伪指令的用法如下:
.MODEL SMALL
.386P ;这个地方不能少了这个指令.
宏如下:
PUSH_REGS    MACRO    REG1,REG2,REG3,REG4,REG5,REG6,REG7,REG8
    IFNB    <REG1>
        PUSH    REG1
    ENDIF
    IFNB    <REG2>
        PUSH    REG2
    ENDIF
    IFNB    <REG3>
        PUSH    REG3
    ENDIF
    IFNB    <REG4>
        PUSH    REG4
    ENDIF
    IFNB    <REG5>
        PUSH    REG5
    ENDIF
    IFNB    <REG6>
        PUSH    REG6
    ENDIF
    IFNB <REG7>
        PUSH REG7
    ENDIF
    IFNB <REG8>
        PUSH REG8
    ENDIF
ENDM

POP_REGS    MACRO    REG1,REG2,REG3,REG4,REG5,REG6,REG7,REG8
    IFNB    <REG8>
        POP REG8
    ENDIF
    IFNB    <REG7>
        POP REG7
    ENDIF
    IFNB    <REG6>
        POP    REG6
    ENDIF
    IFNB    <REG5>
        POP    REG5
    ENDIF
    IFNB    <REG4>
        POP    REG4
    ENDIF
    IFNB    <REG3>
        POP    REG3
    ENDIF
    IFNB    <REG2>
        POP    REG2
    ENDIF
    IFNB    <REG1>
        POP    REG1
    ENDIF
ENDM



;1.1:将8位REG的低4位的二进制数值转化为相应的16进制的ASCII值
;1.2:这里假设REG的高4位为0,如果不是,则高4位清零
;2:任何一个8位的寄存器
;3:REG
BINTOHEX    MACRO    REG :=<AL>
    AND    REG,0FH
    .IF    REG>9
        ADD    REG,37H
    .ELSE
        ADD    REG,30H
    .ENDIF
ENDM    


;1:显示一个ASCII字符
;2:随便一个ASCII数值
;4:改变的寄存器: AX,BX

DISP_ASCII    MACRO    ASC
    IFNB    <ASC>
    MOV    AL,ASC
    ENDIF
    MOV    AH,0EH
    MOV    BL,07H    ;前景色
    MOV    BH,00H    ;页号
    INT    10H
ENDM

;在原来的位置显示若干个字符
DISP_ASC_LOCATE    MACRO    ASC
    PUSH_REGS AX,BX,CX
    IFNB    <ASC>
    MOV    AL,ASC
    ENDIF
    MOV    AH,09H
    MOV    BL,07H
    MOV    BH,0    
    MOV    CX,1    ;重复次数
    INT    10H
    POP_REGS AX,BX,CX
ENDM

;将BITS位的REG的数值以16进制的形式输出
;这个是一个共用的宏
;必须要.386指令,不然会出错
;改变的寄存器:AX,BX,CX
DISPREG    MACRO    REGBITS:REQ,REG:REQ
    LOCAL    DISPREG1
    MOV    CX,REGBITS
    SHR    CX,2    ;CX=CX/4,386指令
DISPREG1:
    ROL    REG,4        ;取REG的高4位输出,这个是386的指令,不然会出错
    PUSH    REG
    BINTOHEX    
    DISP_ASCII
    POP    REG
    LOOP    DISPREG1
ENDM

;以16进制的形式显示一个8位数
;入口参数:任何一个8立即数、8位寄存器
;返回数值:无
;使用的寄存器: 无
DISP_8    MACRO NUM
    PUSH_REGS AX,BX,CX
    MOV    AL,NUM
    MOV    AH,AL
    DISPREG    8,AX
    POP_REGS AX,BX,CX
ENDM

;1:以16进制的形式显示一个16位数
;2:任何一个16位立即数、16位寄存器
;3:无
;4:无
DISP_16    MACRO    NUM
    PUSH_REGS AX,BX,CX
    MOV    AX,NUM
    DISPREG    16,AX
    POP_REGS AX,BX,CX
ENDM

;1:以16进制的形式显示一个32位数
;2:任何一个32位立即数、32位寄存器
DISP_32    MACRO    NUM
    PUSH_REGS AX,BX,CX
    MOV    EAX,NUM
    DISPREG    32,EAX
    POP_REGS AX,BX,CX
ENDM

;1:获得光标的位置
;3:CH=光标的起始行,CL=光标的结束行
;        DH=行,CL=列
;4: CX,DX
GET_CURSOR    MACRO    
    PUSH_REGS AX,BX
    MOV    BH,0    ;页号
    MOV    AH,3
    INT    10H
    POP_REGS    AX,BX
ENDM

;1:设置光标位置
;2:行号,列号
SET_CURSOR    MACRO    LINES,ARR
    PUSH_REGS AX,BX,DX
    MOV    DH,LINES
    MOV    DL,ARR
    MOV    AH,2
    MOV    BH,0
    INT    10H
    POP_REGS AX,BX,DX
ENDM

;1:屏幕上卷
;2:上卷行数和子窗口的坐标
SCREEN_UP    MACRO    NUM,TOP,LEFT,BOTTOM,RIGHT
    PUSH_REGS AX,BX,CX,DX
    MOV    AL,NUM    ;上卷的行数
    MOV    AH,6        
    MOV    BH,7    ;卷入行的属性
    MOV    CH,TOP;窗口的
    MOV    CL,LEFT
    MOV    DH,BOTTOM
    MOV    DL,RIGHT
    INT    10H
    POP_REGS AX,BX,CX,DX
ENDM

;1:清屏
SCRCLR    MACRO    
    SCREEN_UP    25,0,0,24,79
ENDM

;1:实现换行功能
CRLF        MACRO
    PUSH_REGS AX,BX
    DISP_ASCII 0DH
    DISP_ASCII 0AH
    POP_REGS AX,BX
ENDM    

;1:获得字符串的长度
;2:DS(*)、字符串的首地址
;3:LEN
;4:CX,SI,AL
STR_LEN    MACRO    STR_ADDR,LEN
    MOV    SI,STR_ADDR
    LODSB
    MOV    CX,0
    .WHILE    AL!=0
        INC    CX
        LODSB
    .ENDW
    MOV    LEN,CX
ENDM

;1:显示一个字符串
;2:DS(*)、字符串的首地址+字符串的长度,如果没有指定长度,那么以0为结束符号
DISP_STR    MACRO    STR_ADDR,LEN        
    PUSH_REGS    AX,CX,SI
    MOV    SI,STR_ADDR
    IFNB    <LEN>
        MOV    CX,LEN
            .WHILE    CX>0
                MOV    AL,[SI]
                DISP_ASCII
                INC    SI
                DEC    CX
            .ENDW
    ENDIF
    IFB    <LEN>
        MOV    AL,[SI]
        .WHILE    AL!=0
            DISP_ASCII
            INC    SI
            MOV    AL,[SI]
        .ENDW
    ENDIF
    POP_REGS    AX,CX,SI
ENDM

;1:以16进制的形式显示一个字符串的二进制内容
;2:DS(*)、字符串的首地址+字符串的长度,如果没有指定长度,那么以0为结束符号
DISP_STR_16    MACRO    STR_ADDR,LEN
    PUSH_REGS DX,SI
    MOV    DX,LEN
    MOV    SI,STR_ADDR
    .WHILE    DX>0
        LODSB    
        DISP_8    AL
        DEC    DX
    .ENDW
    POP_REGS DX,SI
ENDM

;1:获得一个字符但是不显示
;3:AL
;4:AX

GET_HIDE_CH    MACRO    
    MOV    AH,0
    INT    16H
ENDM

;1:获得并显示一个字符
;3:AL
;4:AX
GET_CH    MACRO    
    GET_HIDE_CH
    DISP_8 AL
ENDM

;1:输入一个字符串
;2:字符串的首地址
GET_STR    MACRO    STR_ADDR
    PUSH_REGS AX,CX,SI
    MOV    SI,STR_ADDR
    MOV    CX,0                    ;CX是用来保存输入的有效字符的个数的,在这里只有回车和退格不是有效字符
    GET_HIDE_CH        
    .WHILE    AL!=0DH
        .IF    AL==08H            ;处理退格键
            .IF    CX!=0
                DISP_ASCII        ;这个只是光标前移,字符还在
                DISP_ASC_LOCATE ' '        ;清除字符
                DEC    CX        ;有效字符减少一个
                DEC    SI
            .ENDIF
        .ELSE
            MOV        [SI],AL
            DISP_ASCII
            INC    SI
            INC    CX
        .ENDIF
        GET_HIDE_CH
    .ENDW
    MOV    [SI],0
    POP_REGS AX,CX,SI
ENDM

;1:把十进制的STR字符串转化为数值保存在EAX中
;2: DS(*)、数字字符串的首地址,首地址不可以是EBX
;3:EAX
;5:在处理前要对STR进行扫描,保证STR的正确
STRD_TO_EAX    MACRO STR_ADDR
    PUSH_REGS    SI,EBX
    XOR    EBX,EBX
    XOR    EAX,EAX
    MOV    SI,STR_ADDR
    LODSB
    .WHILE    AL != 0
            SUB AL,'0'
            ADD    EBX,EBX    ;EBX=2*EBX
            LEA EBX,[EBX*4+EBX]    ;EBX=5*EBX
            ADD    EBX,EAX
            LODSB
    .ENDW
    MOV    EAX,EBX
    POP_REGS SI,EBX
ENDM

;1:把16进制的STR字符串转化为数值保存在EAX中
;2: DS(*)、数字字符串的首地址
;3:EAX
;5:在处理前要对STR进行扫描,保证STR的正确
STRH_TO_EAX    MACRO STR_ADDR
    PUSH_REGS SI,BX
    XOR    EAX,EAX
    MOV    SI,STR_ADDR
    .WHILE    BYTE PTR [SI] != 0
        MOV    BL,BYTE PTR [SI]
        INC    SI
        .IF    BL>'9'
            SUB    BL,'a'-'9'+1
        .ELSE    
            SUB BL,'0'
        .ENDIF
        SHL    EAX,4
        ADD    AL,BL
    .ENDW
    POP_REGS SI,BX
ENDM
;判断一个字符串是否是合法的十进制字符串
;SI为入口地址
;返回AH=0是,=1不是
ISDEC    MACRO    
    LOCAL NOTDEC,ISDEC_EXIT
    PUSH SI,BX
    MOV    BL,AL
    LODSB
    .WHILE AL!=0
        .IF    AL>'9'
            JMP NOTDEC
        .ELSEIF AL<'0'
            JMP NOTDEC
        .ENDIF
        LODSB
    .ENDW
    XOR AH,AH
    JMP ISDEC_EXIT
NOTDEC:
    MOV    AH,1
ISDEC_EXIT:
    MOV    AL,BL
    POP_REGS BX,SI
ENDM

;判断一个字符串是否是合法的16进制数
ISHEX    MACRO
    LOCAL ISHEX_EXIT,ISHEX_LOP
    PUSH_REGS BX,SI
    MOV    BL,AL ;保存AL
    XOR AH,AH
ISHEX_LOP:
    LODSB
    OR AL,AL
    JZ    ISHEX_EXIT
    .IF AL>='0'
        .IF AL<='9'
            JMP ISHEX_LOP
        .ENDIF
    .ENDIF
    
    .IF AL>='A'
        .IF AL<='F'
            JMP ISHEX_LOP
        .ENDIF
    .ENDIF

    .IF AL>='a'
        .IF AL<='f'
            JMP ISHEX_LOP
        .ENDIF
    .ENDIF
    MOV AH,1
    JMP ISHEX_EXIT
ISHEX_EXIT:
    MOV    AL,BL
    POP_REGS BX,SI
ENDM    

3 楼

谢谢你了!
我研究先!

4 楼

我们学的是8086的指令
我看不懂你的指令哦
你能不能给我一个显示16位二进制数的程序!
谢谢了

我来回复

您尚未登录,请登录后再回复。点此登录或注册