Last active
March 15, 2017 21:24
-
-
Save armut/9ec700b43e9890e401b4ccd1facf4415 to your computer and use it in GitHub Desktop.
Kaprekar number finder in (linux) assembly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
section .text | |
global _start | |
_start: | |
MOV CX, 999 ; The program will find first 1000 kaprekar numbers starting from 999. | |
MAIN: MOV DX, 0 ; Empty the DX at start just for safety. | |
MOV AX, CX ; Get the current number to AX. | |
MOV BX, 10 ; Load 10 to BX to use in divisions. | |
COUNTER: DIV BL ; Perform the division. | |
MOV AH, 0 ; Empty AH for the next time. | |
INC DX ; Count the digit. | |
CMP AL, 0 ; Check if the division yielded a zero which means that we must stop dividing it by 10. | |
JE ISKAPR ; So, we got the digit count. All set to go. | |
JMP COUNTER ; Else, continue dividing and counting. | |
ISKAPR: MOV AX, 10 ; Load 10 to AX in order it to exponentiate. | |
PUSH CX ; Backup the original number which we are testing if it is Kaprekar or not. | |
SUB DX, 1 ; Decrease digit count by 1. (For loop to exponentiate AX truly. Otherwise it will yield one unnecessary 0.) | |
MOV CX, DX ; Set counter to the digit count. | |
CMP CX, 0 ; Check if the digit count 0 or not. | |
JE CONT ; If it is, then this number is one-digit. No need to the loop. 10 is enough. | |
POW: MUL BX ; Perform AX * BX. (BX is 10, remember.) | |
LOOP POW ; Loop digit count times. | |
; At the end of this loop, we have got 10^DX in the register AX. | |
CONT: POP CX ; Restore CX to its original value. (This is the number which we are looking for its Kaprekar-ity. | |
PUSH AX ; Backup AX which we evaluated in the POW loop. (If the branch was taken at JE CONT line, AX would be 10.) | |
MOV AX, CX ; Load CX to AX. In order to take its square. | |
MUL AX ; Now perform AX * AX. The result is stored in (DX AX) which is equal to AX^2. | |
POP BX ; Pop the once restored number. (Which was the result of the POW loop or 10 without the loop.) | |
DIV BX ; Perform AX / BX. Which will yield a result in modulus in DX and divident in AX which we need to sum. | |
ADD AX, DX ; Sum them up into AX. | |
SUB AX, CX ; Now, the most breathtaking part. Compare the sum with the original number by subtracting them. | |
JZ KAPR ; If the result is 0, which means AX = CX, this number is a Kaprekar number. Jump to Kaprekar. | |
LOOP MAIN ; Else, it is not. Start over again with the next number. | |
KAPR: PUSH CX ; Store the Kaprekar number in the stack. | |
LOOP MAIN ; Start over again with the next number. | |
MOV AX, 1 ; 'exit' system call. | |
MOV BX, 0 ; Return 0. | |
INT 80H ; Call the kernel. | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
OBJS = kaprekar.s | |
ASM = nasm | |
FLAGS = -f elf -g | |
OBJ_NAME = kaprekar.o | |
EXE_NAME = kaprekar | |
LINK = ld -m elf_i386 -o $(EXE_NAME) $(OBJ_NAME) | |
all: | |
$(ASM) $(FLAGS) $(OBJS) | |
link: | |
$(LINK) | |
clean: | |
rm $(OBJ_NAME) | |
rm $(EXE_NAME) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment