News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

SHR division

Started by Turtle16, March 23, 2005, 04:17:09 PM

Previous topic - Next topic

Turtle16

I need help with using SHR to divide by 2.  My code seems to add the results together rather than display them individually.  Even numbered values enter code label D2 and should continue to divide by 2 if they are even. Here's the code.



       TITLE Message         (prog.asm)
       ;*********************************************************************
       ;
       ;
       ;
       ;
       ; Program Description:
       ;
       ;*********************************************************************








   INCLUDE Irvine16.inc

      .DATA
openMsg      DB   'Program 2', 0dh, 0ah
      DB   'Title: Hailstone ', 0dh, 0ah
      DB   'File: progl.asm', 0dh, 0ah
      DB   'Date ', 0dh, 0ah
      DB   'Author: ', 0dh, 0ah, 0
      
      start    BYTE 'Enter a seed (1 to 130): ', 0
      range    BYTE 'The seed is out of range', 0
      again   BYTE 'Would you like to generate another sequence? (Y/N)', 0
      theEnd  BYTE 'The End', 0
      multiply BYTE 'multiply by 3 and add 1',0
      divide   BYTE 'DIVIDE', 0
      answer   BYTE 'Y', 0
   
      
      
      seed   BYTE 0, 0
      
captMsg      DB   'Hailstone Program', 0dh, 0ah, 0ah, 0

      .CODE
main      PROC
      mov   ax, @data             ; start
      mov   ds, ax                   ;put start of data segment into ds
      mov   dx, OFFSET openMsg    ;point to opening message
      call    WriteString                ;use library routine to display message
      mov   dx, OFFSET captMsg    ;point to capture message
      call    WriteString               ;use library routine to display message
L2:      mov   dx, OFFSET start        ;ask user to input the seed
      call    WriteString                ;display the question on the screen
      call    ReadHex                  ;read the seed input
      mov    seed, al                ;stored value in seed variable
      cmp   seed, 1                 ;see if seed = 1
      je   TE                     ;end the program
      cmp   seed, 0                 ;see if input is <= 0         
      jbe   Ran                    ;display 'Out of Range' and ask for another seed
      cmp   seed, 131             ;see if input is >= 131
      jae   Ran                    ;display 'Out of Range' and ask for another seed
      and   al, 1                    ;determine if the input value is even or odd
      jz   D2                     ;if input value is even then jump to D2
      jnz   M3                    ;if input value is odd then jump to M3
      
Ran:      call    Crlf                    ;line break         
      mov   dx, OFFSET range    ;call the range value
      call   WriteString               ;display 'Out of range' message
      call   Crlf                      ;line break
      jmp   L2                   ;jump to prompt for a new seed
            
D2:      mov   al, seed            ;move the seed value into the lower half of ax
      shr   al, 1                    ;shift al once to divide by 2
      mov   seed, al              ;move al back to the seed variable
      call   Crlf                      ;line break
      mov    dx, OFFSET seed       ;call the seed value
      call   WriteDec             ;write the seed value to the screen
      call   Crlf                     ;line break
      test   seed, 1                 ;
      jz   D2                    ;
      cmp   seed, 1               ;compare the seed to 1
      je   TE                  ;jump to the end if seed = 1
      call   Crlf                    ;line break
      mov   dx, OFFSET again   ;call the again string question
      call   WriteString            ;ask if they would like to do it again
      call   ReadChar            ;read the users input
      mov   bl, al                 ;move the input into the lower half of bx
      cmp   bl, answer          ;compare the answer give to 'Y'
      call   Crlf                   ;line break
      call   Crlf                   ;line break
      je   L2                  ;if answer and bl are = then jump to L2 to start again
      je   TE                 ;if answer is not = to bl then jump to the end
      
      
M3:      call   Crlf                  ;
      mov    dx, OFFSET multiply   ;
      call   WriteString             ;
      jmp   TE                 ;
      
      
TE:      call    Crlf                   ;      
      mov    dx, OFFSET theEnd   ;
      call    WriteString              ;
      call   Crlf                      ;calls a new line
      

         
      exit                       ;exit the program
main      ENDP                  ;assembler directive for end of the main
      END   main              ;assembler directive for end of the




MichaelW

I don't think your problem is with the SHR instruction; it will correctly divide the value in AL by two, and as long as the value is even, no remainder will be lost.

Some problems I see:

This sequence would depend on Crlf preserving the flags (not likely), and the second JE can never execute. You are not otherwise using the value in BL, so it would be more efficient to just compare AL directly.

mov bl, al ;move the input into the lower half of bx
cmp bl, answer ;compare the answer give to 'Y'
call Crlf ;line break
call Crlf ;line break
je L2 ;if answer and bl are = then jump to L2 to start again
je TE ;if answer is not = to bl then jump to the end


And an inefficiency:

You are not otherwise using the value in AL, so it would be more efficient to just shift the variable directly.

D2: mov al, seed ;move the seed value into the lower half of ax
shr al, 1 ;shift al once to divide by 2
mov seed, al ;move al back to the seed variable

eschew obfuscation

BigDaddy

This would be a great problem to solve using your debugger, even if it's just DEBUG.  You can trace through your code while looking at your listing.  (You might have to turn the listing on.)  You'd immediately see that the code doesn't send you where you think it should.