又是一道:来个例子吧
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
相应的对比下简单的C语言例子:
void main()
{
 int i,j,m;
 for(i=1;i<10;i++)
    {
     for(j=1;j<i+1;j++)
        {
         m=i*j;
         printf("%d*%d= %d ",j,i,m);
         }
     printf("\n");
     }
 }