ASSEMBLY - how to do sum between two numbers(interval)

后端 未结 4 448
野的像风
野的像风 2021-01-26 03:45

Hey guys can you help? I dont know how to do sum between two numbers For example :

first number>1

second number>5

sum w

4条回答
  •  清酒与你
    2021-01-26 04:19

    Here is the solution for EMU8086 :

    .stack 100h
    
    .data
    
    msj1  db 'Enter first number: $'
    
    msj2  db 'Enter second number: $'
    
    num1  dw ?  ;FIRST  NUMBER OF INTERVAL.
    
    num2  dw ?  ;SECOND NUMBER OF INTERVAL.     
    
    str   db 6         ;MAX NUMBER OF CHARACTERS ALLOWED (4).
          db ?         ;NUMBER OF CHARACTERS ENTERED BY USER.
          db 6 dup (?) ;CHARACTERS ENTERED BY USER. 
    
    crlf  db 13,10,'$'  ;LINE BREAK.
    
    plus  db '+$'  ;PLUS SIGN TO DISPLAY. 
    
    back  db 8,'$' ;CURSOR WILL MOVE ONE PLACE BACK (TO THE LEFT). 
    
    ekual db '=$'  ;EQUAL SIGN TO DISPLAY. 
    
    suma  dw 0  ;SUMATORY OF ALL NUMBERS BETWEEN NUM1 AND NUM2.
    
    .code          
    
    ;INITIALIZE DATA SEGMENT.
      mov  ax, @data
      mov  ds, ax
    
    ;DISPLAY MESSAGE FOR FIRST NUMBER.
      mov  ah, 9
      mov  dx, offset msj1
      int  21h
    
    ;CAPTURE NUMBER AS STRING.
      mov  ah, 0Ah
      mov  dx, offset str
      int  21h
    
    ;CONVERT CAPTURED NUMBER FROM STRING TO NUMERIC.
      mov  si, offset str ;PARAMETER FOR STRING2NUMBER.
      call string2number
      mov  num1, bx      ;RETURNED VALUE.
    
    ;DISPLAY TWO LINE BREAKS.
      mov  ah, 9
      mov  dx, offset crlf
      int  21h
    
      mov  ah, 9
      mov  dx, offset crlf
      int  21h
    
    ;DISPLAY MESSAGE FOR SECOND NUMBER.
      mov  ah, 9
      mov  dx, offset msj2
      int  21h
    
    ;CAPTURE NUMBER AS STRING.
      mov  ah, 0Ah
      mov  dx, offset str
      int  21h
    
    ;CONVERT CAPTURED NUMBER FROM STRING TO NUMERIC.
      mov  si, offset str ;PARAMETER FOR STRING2NUMBER.
      call string2number
      mov  num2, bx      ;RETURNED VALUE.
    
    ;DISPLAY TWO LINE BREAKS.
      mov  ah, 9
      mov  dx, offset crlf
      int  21h
    
      mov  ah, 9
      mov  dx, offset crlf
      int  21h
    
    ;ASURE FIRST NUMBER IS LESS THAN THE SECOND.
      mov  ax, num1
      cmp  ax, num2
      jbe  fine       ;IF AX < NUM2 JUMP FINE.
      xchg ax, num2   ;EXCHANGE : NUM2=AX, AX=NUM2.
      mov  num1, ax   ;NUM1=NUM2.
    fine:
    
    ;DISPLAY THE INTERVAL.
      call display_interval  
    
    ;WAIT UNTIL USER PRESS ANY KEY.
      mov  ah,7
      int  21h
    
    ;FINISH PROGRAM.
      mov  ax, 4c00h
      int  21h           
    
    ;------------------------------------------
    ;DISPLAY ALL NUMBERS BETWEEN NUM1 AND NUM2
    ;SEPARATED BY '+' AND DISPLAYS THE SUM
    
    proc display_interval
    
    interval:    
    ;ADD CURRENT NUMBER TO SUMA.
      mov  ax, num1       ;AX = CURRENT NUMBER.
      add  suma, ax
    ;CONVERT CURRENT NUMBER TO STRING TO DISPLAY IT.
      call dollars        ;FILL "STR" WITH '$'. NEEDED TO DISPLAY.
      call number2string  ;PARAMETER = AX. RETURNS IN VARIABLE "STR".
    ;DISPLAY NUMBER CONVERTED TO STRING.
      mov  ah, 9
      mov  dx, offset str
      int  21h
    ;DISPLAY PLUS SIGN.
      mov  ah, 9
      mov  dx, offset plus
      int  21h
    ;NEXT NUMBER TO DISPLAY.
      inc  num1
      mov  ax, num1
      cmp  ax, num2
      jbe  interval   ;IF AX <= NUM2 THEN REPEAT.
    
    ;DISPLAY THE SUMA.
    
    ;DISPLAY BACKSPACE (TO DELETE LAST PLUS SIGN).
      mov  ah, 9
      mov  dx, offset back
      int  21h
    
    ;DISPLAY EQUAL SIGN.
      mov  ah, 9
      mov  dx, offset ekual
      int  21h
    
    ;CONVERT SUMA TO STRING TO DISPLAY IT.
      call dollars        ;FILL "STR" WITH '$'. NEEDED TO DISPLAY.
      mov  ax, suma
      call number2string  ;PARAMETER = AX. RETURNS IN VARIABLE "STR".
    
    ;DISPLAY NUMBER CONVERTED TO STRING.
      mov  ah, 9
      mov  dx, offset str
      int  21h
    
      ret
    endp  
    
    ;------------------------------------------
    ;CONVERT STRING TO NUMBER IN BX.
    ;SI MUST ENTER POINTING TO THE STRING.
    
    proc string2number
    ;MAKE SI TO POINT TO THE LEAST SIGNIFICANT DIGIT.
      inc  si ;POINTS TO THE NUMBER OF CHARACTERS ENTERED.
      mov  cl, [ si ] ;NUMBER OF CHARACTERS ENTERED.                                         
      mov  ch, 0 ;CLEAR CH, NOW CX==CL.
      add  si, cx ;NOW SI POINTS TO LEAST SIGNIFICANT DIGIT.
    ;CONVERT STRING.
      mov  bx, 0
      mov  bp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
    repeat:         
    ;CONVERT CHARACTER.                    
      mov  al, [ si ] ;CHARACTER TO PROCESS.
      sub  al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
      mov  ah, 0 ;CLEAR AH, NOW AX==AL.
      mul  bp ;AX*BP = DX:AX.
      add  bx,ax ;ADD RESULT TO BX. 
    ;INCREASE MULTIPLE OF 10 (1, 10, 100...).
      mov  ax, bp
      mov  bp, 10
      mul  bp ;AX*10 = DX:AX.
      mov  bp, ax ;NEW MULTIPLE OF 10.  
    ;CHECK IF WE HAVE FINISHED.
      dec  si ;NEXT DIGIT TO PROCESS.
      loop repeat ;COUNTER CX-1, IF NOT ZERO, REPEAT.
    
      ret 
    endp    
    
    ;------------------------------------------
    ;FILLS VARIABLE STR WITH '$'.
    ;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
    ;THE STRING WILL BE DISPLAYED.
    
    proc dollars                 
      mov  si, offset str
      mov  cx, 6
    six_dollars:      
      mov  bl, '$'
      mov  [ si ], bl
      inc  si
      loop six_dollars
    
      ret
    endp  
    
    ;------------------------------------------
    ;NUMBER TO CONVERT MUST ENTER IN AX.
    ;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
    ;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
    ;ORDER TO CONSTRUCT STRING (STR).
    
    proc number2string
      mov  bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
      mov  cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
    cycle1:       
      mov  dx, 0 ;NECESSARY TO DIVIDE BY BX.
      div  bx ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER.
      push dx ;PRESERVE DIGIT EXTRACTED FOR LATER.
      inc  cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
      cmp  ax, 0  ;IF NUMBER IS
      jne  cycle1 ;NOT ZERO, LOOP. 
    ;NOW RETRIEVE PUSHED DIGITS.
      mov  si, offset str
    cycle2:  
      pop  dx        
      add  dl, 48 ;CONVERT DIGIT TO CHARACTER.
      mov  [ si ], dl
      inc  si
      loop cycle2  
    
      ret
    endp  
    

    Next is your code with some changes, now it takes two parameters from stack and internally puts them in variables num1 and num2. I'm not taking care of the parameters for all the "print" :

    proc display_interval
    
    ;RETRIEVE PARAMETERS.
        pop   ax    ;RETURN ADDRESS.
        pop   num2  ;NUM2.
        pop   num1  ;NUM1.
        push  ax    ;RETURN ADDRESS BACK (NECESSARY FOR "RET").
    
        print msg4
    interval:    
        ;ADD CURRENT NUMBER TO SUMA.
          mov  ax, x       ;AX = CURRENT NUMBER.
          add  k, ax
        ;CONVERT CURRENT NUMBER TO STRING TO DISPLAY IT.
          call dollars        ;FILL "STR" WITH '$'. NEEDED TO DISPLAY.
          call number2string  ;PARAMETER = AX. RETURNS IN VARIABLE "STR".
        ;DISPLAY NUMBER CONVERTED TO STRING.
          mov  ah, 9
          mov  dx, offset str
          int  21h
        ;DISPLAY PLUS SIGN.
          mov  ah, 9
          mov  dx, offset plus
          int  21h
        ;NEXT NUMBER TO DISPLAY.
          inc  x
          mov  ax, x
          cmp  ax, y
          jbe  interval   ;IF AX <= NUM2 THEN REPEAT.
    
        ;DISPLAY THE SUMA.
    
        ;DISPLAY BACKSPACE (TO DELETE LAST PLUS SIGN).
          print back
    
        ;DISPLAY EQUAL SIGN.
          print equal
    
        ;CONVERT SUMA TO STRING TO DISPLAY IT.
          call dollars        ;FILL "STR" WITH '$'. NEEDED TO DISPLAY.
          mov  ax, k
          call number2string  ;PARAMETER = AX. RETURNS IN VARIABLE "STR".
    
        ;DISPLAY NUMBER CONVERTED TO STRING.
          mov  ah, 9
          mov  dx, offset str
          int  21h
    
          ret
    endp  
    

    Procedure "display_interval" should be called like this :

    mov  ax, 1
    push ax      ;FIRST PARAMETER.
    mov  ax, 5
    push ax      ;SECOND PARAMETER.
    call display_interval
    

提交回复
热议问题