回 帖 发 新 帖 刷新版面

主题:怎么输出九九乘法表啊

怎么输出九九乘法表啊

回复列表 (共5个回复)

沙发


CR  MACRO                ;换行宏
    MOV    AH,2
    MOV    DL,0AH
    INT    21H
    MOV    DL,0DH
    INT    21H
    ENDM
SHOW    MACRO            ;显示乘积的宏
    LOCAL  NEXT1
    MOV    AH,0
    AAM                  ;因为乘积最大为81,所以可采用BCD码乘法调整
    MOV    DX,AX
    MOV    AH,2
    OR     DX,3030H
    XCHG   DH,DL
    CMP    DL,30H        ;这里加了个判断,用于判断10位是否为零,例如乘积为09,则打头的零就不用输出
    JZ     NEXT1
    INT    21H
NEXT1:    
    XCHG   DH,DL
    INT    21H
    MOV    DL,20H
    INT    21H
    ENDM
DSEG    SEGMENT
SEN     DB    ?,'*',?,'= $'        ;为输出乘式做准备,第一个问号处存放被乘数,第二个放乘数
DSEG    ENDS
CSEG    SEGMENT
        ASSUME CS:CSEG,DS:DSEG
MAIN:   MOV    AX,DSEG
        MOV    DS,AX
        MOV    BL,1                ;在控制行数的同时,控制乘数的最大值(1-9)
NEXT:   MOV    BH,BL           
        INC    BH                  ;这里的BH用于存放(BH)+1,用于控制被乘数的循环乘积
        MOV    CL,1                ;CL存放被乘数,从1开始乘直到等于(BH)的值
NEXT0:  MOV    AL,BL
        MOV    AH,0
        MUL    CL
        PUSH   AX
        MOV    AH,9
        MOV    SEN,CL               ;在这里开始存放显示的乘数、被乘数
        ADD    SEN,30H
        MOV    SEN+2,BL
        ADD    SEN+2,30H
        LEA    DX,SEN
        INT    21H                  ;输出乘式
        POP    AX
        SHOW                        ;显示乘积
        INC    CL
        CMP    CL,BH
        JB     NEXT0
        CR
        INC    BL
        CMP    BL,10
        JB     NEXT
        MOV    AX,4C00H
        INT    21H
CSEG    ENDS
        END    MAIN

板凳


可以输出[em2]

3 楼

呵呵,今天刚好写了一个,其中打印数的函数对这个问题来说复杂了一点,但有现成的函数,就用上了,程序中全部打印的是一个一位数,所以其实只需要+30h后输出dl就行了.

;程序功能:输入乘法表.

.model small,stdcall

.data
    a dw 0
    b dw 0
    prompt db "A good table:",0ah,0dh,'$'
    over db 0ah,0dh,"Press key to continue...$"

.code

println proc near ; a function to get a new line
    mov ah,02h
    mov dl,0ah
    int 21h
    mov dl,0dh
    int 21h
    ret ;return the function which call it.
println endp

;函数功能:把存在ax寄存器里的二进制数用十进制打印出来.
printaxd proc near
    push ax
    push bx
    push cx
    push dx
    push si
    push di
    push bp

    mov bx,10000d ;二个字节的数最大就3万多.
    mov ch,0 ;还没出现第一个要打印的数(最高位的非0不需要打印)
    mov cl,5 ;最多有五位,所以一共除五次.
    mov si,ax ;哈哈,寄存器太聪明了.
go:
    mov ax,si
    mov dx,0 ;既然是除法,就要保证高位的绝对值最小.
    div bx
    dec cl ;除一次就减一次.
    mov di,ax ;除完就把商移走,位置让出来给bx/10
    mov si,dx ;保证余数.

    ;实现bx/10.
    mov ax,bx
    mov bx,10 ;记住乘除法运算不能用立即数.
    mov dx,0 ; 实际上dl的最大值也就是9小于10,但为了保险和习惯,还是用这一句.
    div bx
    mov bx,ax
    mov ax,di 
    cmp cl,0 ;如果到最后一位了,无论是0还是不为0,都要打印了.
    jz next
    or ch,al
    jz go
next:
    mov ch,1 ;有打印的了
    mov dl,al
    add dl,30h
    mov ah,02h
    int 21h
    cmp cl,0
    jnz go
    

    pop bp
    pop di
    pop si
    pop dx
    pop cx
    pop bx
    pop ax

    ret ; This line cann't be forgotten.
printaxd endp

main proc far
    mov ax,@data
    mov ds,ax

    lea dx,prompt ;print the prompt
    mov ah,09h
    int 21h 

    mov a,1
    mov b,1
go:
    mov ax,a
    call printaxd
    mov ah,02
    mov dl,'*'
    int 21h
    mov ax,b
    call printaxd
    mov ah,02
    mov dl,'='
    int 21h
    mov ax,a
    mul b
    call printaxd
    mov ah,02
    mov dl,' '
    int 21h

    inc a
    mov ax,b
    cmp ax,a
    jns go
    call println
    mov a,1
    inc b
    cmp b,10
    js go

exit:
    lea dx,over ;print the prompt
    mov ah,09h
    int 21h 
    mov ah,01h ;to have a stop
    int 21h

    mov ah,4ch ; Game Over
    int 21h
main endp
end main

4 楼


谢谢啊

5 楼

第一个正确的,但第二有点问题哦

我来回复

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