0

I am tasked to right a program to check if two numbers are Amicable numbers, there is supposed to be an input by the user of 2 in size of 4 byte numbers, the program works perfectly in turbo debugger but it seems when I try to run the program as it is with dosbox it wont let me register the second input by the user, I am using one proc for the number input and another proc to find all the dividers of said number.


; Lab assignment 7 - Amicable Numbers

.MODEL SMALL
.STACK 100h
.DATA
ENTERkey        DB 13
TWO DD 2
TEN DD 10
SUM DD ?
NUM1 DD ?
SUMNUM1 DD ?
NUM2 DD ?
SUMNUM2 DD ?



NotAmicableMessage DB 13,10,'Not Amicable Numbers',13,10,'$'
AmicableMessage DB 13,10,'Amicable Numbers',13,10,'$'
.386
.CODE



; int getNum();
getNum PROC NEAR
    PUSH EBX
    PUSH CX
    PUSH DX

    MOV EBX, 0
    MOV EAX, 0
    MOV CX, 10
LOOPINPUT:
    MOV AH, 1
    INT 21h
    CMP AL, ENTERkey
    JE FINISH
    SUB AL ,'0'
    MOV AH, 0
    XOR EAX, EBX
    XOR EBX, EAX
    XOR EAX, EBX
    MUL TEN
    XOR EAX, EBX
    XOR EBX, EAX
    XOR EAX, EBX
    ADD EBX, EAX
    LOOP LOOPINPUT


FINISH:
    MOV EAX, EBX
    POP DX
    POP CX
    POP EBX
    RET
ENDP


; int Pnum(int EAX);
Pnum PROC NEAR

    PUSH BP
    MOV BP, SP
    MOV SUM, 0
    MOV EAX, [BP+4]
    PUSH EBX
    PUSH ECX
    PUSH EDX

    MOV BP, SP
    MOV EBX, EAX
    DIV TWO
    MOV ECX, EAX
    CMP ECX, 0
    JE DONE
LOOPNUM:
    MOV EDX, 0
    MOV EAX, EBX
    DIV ECX
    CMP EDX, 0
    JNE CONTINUE
    ADD SUM, ECX
CONTINUE:
    DEC ECX
    CMP ECX, 0
    JNE LOOPNUM
    MOV EAX, SUM
DONE:
    POP EDX
    POP ECX
    POP EBX
    POP BP

    RET
ENDP



MAIN:
    MOV AX, @DATA
    MOV DS, AX

    CALL getNum ; Number 1
    PUSH EAX
    MOV NUM1, EAX
    CALL Pnum
    MOV SUMNUM1, EAX

    CALL getNum
    PUSH EAX
    MOV NUM2, EAX
    CALL Pnum
    MOV SUMNUM2, EAX

    CMP NUM1, EAX
    JNE notAMICABLE
    MOV EAX, SUMNUM1
    CMP NUM2, EAX
    JNE notAMICABLE

    MOV DX, OFFSET AmicableMessage
    MOV AH, 9
    INT 21h
    JMP SOF

    notAMICABLE:
    MOV DX, OFFSET NotAmicableMessage
    MOV AH, 9
    INT 21h


    SOF:
    MOV AH, 4ch
    INT 21h
END MAIN

Here is the first input and once I press enter I cannot enter the second number

Here is the first input and once I press enter I cannot enter the second number

Again, the input works fine once I run the program in TD mode

Tommy Mei
  • 13
  • 2
  • 1
    Looks like you don't zero EDX before the first `div`. Also, don't use DIV to divide by 2 in the first place. Computers use binary; you can just right shift with `shr eax,1`. Under a better OS, #DE exceptions would reliably result in a message from the OS, not silent failure. Also, under multi-tasking OS like Linux or Windows, debuggers can be fully non-intrusive so you wouldn't have this Heisenbug situation where it only appears not under the debugger. – Peter Cordes May 17 '20 at 23:10
  • Thank you it is fixed now! Regarding " shr eax,1" I'll consider doing so in the future – Tommy Mei May 17 '20 at 23:15
  • 2
    Also, around MUL, is that an XOR-swap?? Use `xchg eax, ebx` like a normal person. XOR-swap is basically never useful. Or better, since you're using 386 instructions (32-bit operand-size) anyway, use [`imul ebx, ebx, 10`](https://www.felixcloutier.com/x86/imul). Or use LEA to multiply by 10 and add a digit in 2 instructions even more efficiently. [NASM Assembly convert input to integer?](https://stackoverflow.com/a/49548057) – Peter Cordes May 18 '20 at 00:01

0 Answers0