# Printing all permutations of digits of a number

So, a long time ago, I've made a program that prints all the permutations of digits of a number in AEC. Now I have refactored it a bit, and I would be interested in what you think about it.

;Advanced example: implementing the permutation algorithm.
AsmStart
debug=0
macro pushIntegerToTheSystemStack x
{
sub esp,4
fld dword [x]
fistp dword [esp]
}
macro pushPointerToTheSystemStack x
{
sub esp,4
lea ebx,[x]
mov [esp],ebx
}
macro pushStringToTheSystemStack x
{
sub esp,4
mov dword [esp],x
}
format PE console
entry start

include 'win32a.inc'

section '.text' code executable
start:
jmp enterNumber$enterNumber db "Enter a whole number (1 - 1'000'000).",10,0 enterNumber$:
pushStringToTheSystemStack enterNumber
call [printf]
pushPointerToTheSystemStack original
jmp floatSign$floatSign db "%f",0 floatSign$:
pushStringToTheSystemStack floatSign
call [scanf]
jmp permutationString$permutationString db "The permutations of its digits are:",10,0 permutationString$:
pushStringToTheSystemStack permutationString
call [printf]
AsmEnd
numberOfPermutations:=0
numberOfDigits:=0
i:=0
While i<10
countDigits[i] := 0
i:=i+1
EndWhile
While original>0
numberOfDigits := numberOfDigits + 1
lastDigit := mod (original, 10)
countDigits [lastDigit] := countDigits (lastDigit) + 1
original := (original - lastDigit) / 10
EndWhile
AsmStart
if debug=1
AsmEnd
i:=0
While i<10
subscript:=4*i
AsmStart
fld dword [subscript]
fistp dword [subscript]
mov ebx,[subscript]
pushIntegerToTheSystemStack (countDigits+ebx)
pushStringToTheSystemStack integerSign
call [printf]
AsmEnd
i:=i+1
EndWhile
AsmStart
pushStringToTheSystemStack newLineString
call [printf]
AsmEnd
AsmStart
end if
AsmEnd
topOfMyStack:=1
myStack [ (numberOfDigits + 1) ] := 0
While topOfMyStack>0
currentNumberOfDigits := myStack ( topOfMyStack * ( numberOfDigits + 1 ) )
i:=0
While i<currentNumberOfDigits
currentNumber ( i ) := myStack ( topOfMyStack * ( numberOfDigits + 1 ) + ( i + 1 ) )
i:=i+1
EndWhile
AsmStart
if debug=1
AsmEnd
i:=0
While i<currentNumberOfDigits
subscript:=i*4
AsmStart
fld dword [subscript]
fistp dword [subscript]
mov ebx,[subscript]
pushIntegerToTheSystemStack (currentNumber+ebx)
pushStringToTheSystemStack integerSign
call [printf]
AsmEnd
i:=i+1
EndWhile
AsmStart
pushStringToTheSystemStack newLineString
call [printf]
AsmEnd
AsmStart
end if
AsmEnd
topOfMyStack:=topOfMyStack-1
If currentNumberOfDigits=numberOfDigits
numberOfPermutations:=numberOfPermutations+1
i:=0
While i<numberOfDigits
subscript:=i*4
AsmStart
fld dword [subscript]
fistp dword [subscript]
mov ebx,[subscript]
pushIntegerToTheSystemStack (currentNumber+ebx)
pushStringToTheSystemStack integerSign
call [printf]
AsmEnd
i:=i+1
EndWhile
AsmStart
pushStringToTheSystemStack newLineString
call [printf]
AsmEnd
Else
i:=0
While i<10
counter:=0
j:=0
While j<currentNumberOfDigits
If currentNumber(j)=i
counter:=counter+1
EndIf
j:=j+1
EndWhile
If counter < countDigits(i)
topOfMyStack := topOfMyStack + 1
myStack (topOfMyStack * (numberOfDigits + 1) ) := currentNumberOfDigits + 1
j:=0
While j < currentNumberOfDigits
myStack (topOfMyStack * (numberOfDigits + 1) + (j + 1)) := currentNumber (j)
j:=j+1
EndWhile
myStack (topOfMyStack * (numberOfDigits + 1) + (j + 1) ) := i
EndIf
i:=i+1
EndWhile
EndIf
EndWhile
AsmStart
jmp numberOfPermutationsString$numberOfPermutationsString: db "The total number of permutations was: %d",10,0 numberOfPermutationsString$:
pushIntegerToTheSystemStack numberOfPermutations
pushStringToTheSystemStack numberOfPermutationsString
call [printf]
invoke system,_pause
invoke exit,0

_pause db "PAUSE",0
integerSign db "%d",0
newLineString db 10,0

original dd ?
result dd ?
lastDigit dd ?
numberOfDigits dd ?
countDigits dd 11 dup(?)
subscript dd ?
myStack dd 1000 dup(?)
topOfMyStack dd ?
counter dd ?
i dd ?
currentNumber dd 11 dup(?)
currentNumberOfDigits dd ?
j dd ?
numberOfPermutations dd ?

library msvcrt,'msvcrt.dll'
import msvcrt,printf,'printf',system,'system',exit,'exit',scanf,'scanf'
AsmEnd


The 32-bit Windows executable is available here, it's called permutations.exe.

• Why assembly? These days it's not a common choice. Commented Apr 29, 2020 at 13:29
• @Reinderien, Assembly is used to call C functions "printf" and "scanf". The algorithm is written in AEC. I thought it was obvious. Commented Apr 29, 2020 at 13:59

## Coding style

numberOfDigits:=0
numberOfDigits := numberOfDigits + 1
countDigits[i] := 0
countDigits [lastDigit] := countDigits (lastDigit) + 1
myStack [ (numberOfDigits + 1) ] := 0
myStack (topOfMyStack * (numberOfDigits + 1) ) := currentNumberOfDigits + 1


Throughout the program your use of whitespace and brackets is inconsistent.
Even if you have the choice between [] and () to address array elements, you should choose one of them and stick with your choice.
This fickleness is especially annoying in countDigits [lastDigit] := countDigits (lastDigit) + 1

## Alternative

You can remove the high level subscript:=4*i if you use a scaled address form:

 i:=0
While i<10
AsmStart
fld   dword [i]
fistp dword [subscript]
mov   ebx, [subscript]
pushIntegerToTheSystemStack (countDigits + ebx * 4)
...


## Warning

It's nice that you prompt the user for a non-zero number but your program should actually verify this.