4

Assembly x86 MASM

I have created the following code that will prints out a multiplication table that multiplies 1*1, 1*2, 1*3, ..., 1*10. I want to create a continuous table of 1*1, 1*2, 1*3, ..., 1*10, and another table of 2*1, 2*2, 2*3,...,2*10 and 3*1, 3*2, 3*3,...,3*10 and so forth up to 10*10 using loops rather writing it out each procedure separately. However, I am having difficulty creating the loops. Please can anyone show me. Thank you so very much.

INCLUDE Irvine32.inc
.data
  a dword 1
  b dword 1
  z dword ?
  times byte " * ",0
  equals byte " = ",0
.code
main PROC
        call clrscr
        mov ecx,10
        outloop :
         push ecx
         call printtimes

         call crlf
         inc a
         pop ecx
        loop outloop

        call crlf 

        mov ecx,10
        mov a, 1
        outloop1 :
        push ecx 
        call printtimes1 

        call crlf 
        inc a 
        pop ecx 
        loop outloop1 

        call crlf 

        mov ecx,10
        mov a, 1
        outloop2 :
        push ecx 
        call printtimes2 

        call crlf 
        inc a 
        pop ecx 
        loop outloop2 


        exit

main ENDP



    mymul proc
        mov ecx,a
        mov eax,0
        myloop:
         add eax,b
        loop myloop
        mov z,eax

        ret
    mymul endp



    mymul1 proc

        mov ecx,a
        mov eax,0
        mov b, 1
        inc b
        myloop:
         add eax,b
        loop myloop
        mov z,eax

        ret
    mymul1 endp


    mymul2 proc

        mov ecx,a
        mov eax,0
        mov b, 2
        inc b
        myloop:
         add eax,b
        loop myloop
        mov z,eax

        ret
    mymul2 endp




    printtimes proc

      call mymul
        mov eax,a
        call writedec
        mov edx, offset times
        call writestring
        mov eax,b
        call writedec
        mov edx,offset equals
        call writestring
        mov eax,z
        call writedec
        call crlf
        ret 
     printtimes endp

         printtimes1 proc
      call mymul1
        mov eax,a
        call writedec
        mov edx, offset times
        call writestring
        mov eax,b
        call writedec
        mov edx,offset equals
        call writestring
        mov eax,z
        call writedec
        call crlf
        ret 
     printtimes1 endp

     printtimes2 proc
      call mymul2
        mov eax,a
        call writedec
        mov edx, offset times
        call writestring
        mov eax,b
        call writedec
        mov edx,offset equals
        call writestring
        mov eax,z
        call writedec
        call crlf
        ret 
     printtimes2 endp

end main

The results are (I want this result using nested loops instead but I am having difficulty creating it):

1*1=1 
2*1=2 
3*1=3 
4*1=4 
5*1=5
6*1=6 
7*1=7 
8*1=8 
9*1=9 
10*1=10 

1*2=2 
2*2=4 
3*2=6 
4*2=8 
5*2=10
6*2=12 
7*2=14 
8*2=16 
9*2=18 
10*2=20 


1*3=3 
2*3=6 
3*3=9 
4*3=12 
5*3=15
6*3=18 
7*3=21 
8*3=24 
9*3=27 
10*3=30 
jackson blackson
  • 311
  • 1
  • 3
  • 13
  • 3
    Is that `;1*30 = 30` stuff at the end supposed to be the output? I don't understand what the problem is. Explain which part you're stuck on in figuring out how to write a program that adds and prints in a loop to create multiplication tables. It all sounds pretty straightforward to me, so IDK what part isn't obvious to you. – Peter Cordes Oct 30 '16 at 06:58
  • 1
    I still don't understand why this would be hard, or what part you're having trouble with. Are you running out of registers for an outer-loop counter? You just need to print `j*i=prod` in a `for(i=1..10) for (j=1..10)` loop. You apparently already have printing integers sorted, since you're printing `10` ok (not running into trouble with multi-digit integers that don't work with just `add al, '0'`). – Peter Cordes Oct 31 '16 at 00:34
  • Can you show me a pseudo code? Thank you so much – jackson blackson Oct 31 '16 at 00:52
  • 1
    I just did, in that previous comment. I can do it again with more code and less english: `for(i=1..10) { for (j=1..10) { print j, '*', i, '=', i*j; } }` – Peter Cordes Oct 31 '16 at 00:56
  • I actually did that in my previous code but it went into infinite looping. The first loop is the printing method that will call the multiplication method. But for some odd reason, it went into an infinite loop. – jackson blackson Oct 31 '16 at 01:05
  • 1
    Then use a debugger to look at register values in the infinite loop, and single-step to figure out why it's not taking the branch you expect. A common reason is that function calls might modify registers (not all registers are call-preserved). You should check the Irvine32 calling convention to see what regs they preserve, and keep your counters in call-preserved regs. – Peter Cordes Oct 31 '16 at 01:12

1 Answers1

2
   mov ecx,10
outloop :
    push ecx
    call printtimes
    call crlf
    inc a
    pop ecx
    loop outloop
    call crlf

All the previous is your code to produce the 1st table (1*1=1 2*1=2 ... 10*1=10)
To start using nested loops for outputting all of the tables, you need to surround this code by an extra loop that will

  • reset the a variable to 1
  • increment the b variable

You keep repeating this extra (outer) loop until the b variable has become larger than 10.
For simplification you can dismiss using the ECX register for the inner loop, and also watch for the value of the a variable becoming larger than 10.

    mov     b, 1
OuterLoop:
    mov     a, 1
InnerLoop:
    call    printtimes
    call    crlf
    inc     a
    cmp     a, 10
    jbe     InnerLoop
    call    crlf
    inc     b
    cmp     b, 10
    jbe     OuterLoop

You no longer need printtimes1, printtimes2, mymul1, and mymul2 in your program.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76