-2

I have already written the code to add TWO arrays and Store the result in 3rd array. But the problem occurs while handling the NEGATIVE SIGN Numbers to display with (-) sign. Follow are the code listed below while subtracting the 6th element of array1 with array 2, result is GARBAGE value Need assistance immediately. After running executing's the code, all signed values are not displaying correctly.

 org 100h
 Array1 db 1,3,2,2,2,2,2,2,2,2
 Array2 db 4,5,6,7,8,9,0,1,2,3  
 Array3  db  10 dup (?)


 lea dx, msg1
 mov ah, 9
 int 21h 

 mov cx, 10
 mov bx, 0

 L1001:

  mov     al, Array1 [bx]
  ; Extend (unsigned) AL to AX (to print)    
  mov     ah, 0
  call    printd
 
  mov     ah, 2
  mov     dl, 09 ;TAB Character
  int     21h

  inc     bx
 loop    L1001       ;End Loop1
 
 mov ah,2
 mov dl,10
 int 21h
 mov dl,13
 int 21h

 ; print msg2     
 lea     dx, msg2
 mov     ah, 9
 int     21h

 ; Use loop to print values of Array2                
 mov     cx, 10
 mov     bx, 0       

 L1002:

  mov     al, Array2 [bx]
  ; Extend (unsigned) AL to AX (to print)    
  mov     ah, 0
  call    printd
  
  mov     ah, 2
  mov     dl, 09 ;TAB Character
  int     21h
  inc     bx
loop    L1002   End Loop2

 mov ah,2
 mov dl,10
 int 21h
 mov dl,13
 int 21h

; print msg3    
lea     dx, msg3
mov     ah, 9
int     21h     

mov cx,10
mov bx, 0

L1003:                          ; Main Addition
 mov     al, Array1 [bx]
 sub     al, Array2 [bx]
 mov     Array3 [bx], al
 ; Extend (unsigned) AL to AX (to print)    
 mov     ah, 0
 call    printd

 mov     ah, 2
 mov     dl, 09 ;TAB Character
 int     21h   

 inc     bx
loop    L1003  ; End of lOOP3  


 lea dx, pkey
 mov ah, 9
 int 21h        ; output string at ds:dx

 ; wait for any key....    
 mov ah, 1
 int 21h

 mov ax, 4c00h ; exit to operating system.
 int 21h

 printd  proc

  ; preserve used registers
  push    ax  
  push    bx
  push    cx    
  push    dx

 ; if negative value, print - and call again with -value     
 cmp     ax, 0
 jge     L1

 mov     bx, ax

 ; print -    
 mov     dl, '-'
 mov     ah, 2
 int     21h   

 ; call with -AX             
 mov     ax, bx
 neg     ax
 call    printd
 jmp     L3

L1:

 ; divide ax by 10
 ; ( (dx=0:)ax / cx(= 10) )
 mov     dx, 0
 mov     cx, 10
 div     cx

 ; if quotient is zero, then print remainder              
 cmp     ax, 0
 jne     L2 
    
add dl, '0'
mov ah, 2
int 21h
jmp L3

L2: 
 ; if the quotient is not zero, we first call
 ; printd again for the quotient, and then we
 ; print the remainder.

 ; call printd for quotient:
 call    printd             

 ; print the remainder
 add     dl, '0'
 mov     ah, 2
 int     21h        

L3:
 ; recover used registers
 pop     dx
 pop     cx
 pop     bx
 pop     ax
 ret
printd  endp 

printud  proc ;Print Undecimal Numbers
 push    ax  
 push    bx
 push    cx    
 push    dx

 mov     dx, 0
 mov     cx, 10
 div     cx

 cmp     ax, 0
 jne     L4

 add     dl, '0'
 mov     ah, 2
 int     21h

 jmp     L5

L4:
  call    printud
  add     dl, '0'
  mov     ah, 2
  int     21h        

L5:
  pop     dx
  pop     cx
  pop     bx
  pop     ax
  ret
printud  endp ; 

ret  
 msg1    db  "Array 1 = $"
 msg2    db  "Array 2 =  $"
 msg3    db  "Array 3 =      : $"
 pkey    db "press any key...$" 



                                           
Ali Uzair
  • 3
  • 4
  • Have you tried single step debugging? At what instruction does the garbage first appear? – Erik Eidt Feb 17 '22 at 19:00
  • @ErikEidt Yes! Basically the problem is when we subtract two elements, if the results comes in SIGNED number the program DOES able to display that number. Else the program works fine for unsigned number. – Ali Uzair Feb 17 '22 at 19:04
  • 2
    FYI, I think you mean positive and negative numbers. The terms positive and negative apply to values; whereas signed and unsigned apply to data types (and instructions that manipulate data types). A signed data type can hold both positive and negative numbers (and zero); whereas an unsigned data type can hold only positive numbers (and zero). – Erik Eidt Feb 17 '22 at 19:08
  • @ErikEidt, Exactly you Got it right. So, If the results comes as negative number e.g (1-2 = -1), THE above program won't able to print -1 as an output. – Ali Uzair Feb 17 '22 at 19:21
  • Single step each instruction and verify that every register result is meaningful. For testing purposes, make sure the bad case is the first one in the array. Verify that the memory value for 1-2 is -1 aka 0xFF. Verify that you are passing parameters correctly to `printd` including for the recursive call. The code seems basically right, so it will come down to finding a typo or other on some instruction (or several). – Erik Eidt Feb 17 '22 at 20:19
  • @ErikEidt For testing purposes, I set the VALUE OF 1ST ELEMENT OF ARRY1 (= 1) and the value of 1nd ELEMENT of Array2 (=2), and after subtracting the final result is as follow 255. NOTE: I changed the array size to 1 for testing purposes. – Ali Uzair Feb 17 '22 at 20:33
  • does it skip the code that prints the '-'? What's in `ax` when you do the `cmp ax, 0; jge L1`? – Erik Eidt Feb 17 '22 at 20:36
  • Not a [mcve]; all the code to add arrays seems irrelevant to a bug in the printing part. Also the question isn't specific about what output you do get, or any details from single-step debugging. – Peter Cordes Feb 17 '22 at 21:17
  • For working code to print signed numbers, see [Displaying numbers with DOS](https://stackoverflow.com/q/45904075) – Peter Cordes Feb 17 '22 at 21:22

1 Answers1

2
mov     al, Array1 [bx]
sub     al, Array2 [bx]
mov     Array3 [bx], al
; Extend (unsigned) AL to AX (to print)    
mov     ah, 0
call    printd

You say that your program is having trouble displaying the negative numbers, but your code is never feeding any negative number to the printd routine! Whatever the signed result of the subtraction in AL may be, the mov ah, 0 that follows will produce a positive number in AX and it is AX that printd processes...
You should replace mov ah, 0 by cbw.

But, what is terribly wrong is the placement of the 3 arrays. They can't be at the top of the program like that. The cpu is executing their bytes (data) as if it were instructions (code)!
Move those 3 lines towards the bottom of the source.

It surprised me to see these recursive solutions to display a decimal number. I believe they are correct with one exception though! If you feed printd the negative number -32768 then the program will fall into an infinite loop. This happens because the negation of that particular value is again -32768.
You might want to investigate Displaying numbers with DOS for info about the iterative solution that is surely faster (and could be improved further by outputting the digits all at once).

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • Yeah, the recursion is an odd choice, when simply falling through there would have been expected. – Erik Eidt Feb 18 '22 at 01:09
  • I have moved the following instructions to the end of the program, But now the junk value has been changed. Will you provide a program that will do the task from scratch? So it is better for me to get an Idea where Am I wrong as a beginner. – Ali Uzair Feb 18 '22 at 07:54