covertion celcius to Fahrenheit help...

Started by stijohnforever, October 22, 2005, 03:53:32 AM

Previous topic - Next topic

stijohnforever


#make_COM#

; COM file is loaded at CS:0100h
ORG 100h

.MODEL SMALL
.STACK 200

.DATA

     CRLF DB 0DH,0AH,'$'
     MSG  DB  'Enter integer to be converted to fahrenheit: ','$'
     MSG2 DB  'Result in fahrenheit: ','$'
     C    DB  ?
     RF   DB  ?
     
     
.CODE
.STARTUP

     MOV AX,003H
     INT 10H
     
     LEA DX,MSG
     MOV AH,09H
     INT 21H
     
     MOV AH,01H
     INT 21H
     SUB AL,30H
 
     MOV C,AL
   
   
     MOV  CL,C
     MOV  AL,9
     IMUL CL
     MOV  CL,5
     IDIV CL
     ADD  AL,32
     MOV  RF,AL
   
   
     LEA  DX, CRLF
     MOV AH,09H
     INT 21H
     
     LEA DX,MSG2
     MOV AH,09H
     INT 21H 
           
     MOV DL,RF
     ADD Dl,30H
     MOV Ah,02H
     INT 21H

      
.EXIT
END
:'(  the problem is that the output is letters or some aschii characters. plz help

JFG

Going through your program, I find that in general this is probably what happens:

MOV DL,RF  ; RF = typically, a two decimal digit value
ADD Dl,30H ; assumes DL has a one decimal digit value -
           ; + 30H puts it in letter & misc. ASCII code value range
MOV Ah,02H
INT 21H    ; displays ASCII 39H+ value

You'll therefore have to test for values of RF that require displaying more than just one character, such as 82, 104, or -10.  Writing the code for handling the different cases is just busy work though.  Since you for the purposes of this program you don't have to be able to handle a large range of possible different values, you can get away with doing a ladder of conditional tests like this:

; Handle all cases of RF = [-99, -10].
CMP RF,-10
JG @F
MOV DL, '-'
MOV AH, 02H
INT 21H ; Show the negative sign.
NEG RF ; RF doesn't have to be negative anymore, so make it positive.
MOV AL, RF
MOV CL, 10
DIV CL ; Divide out the one's place value, leaving the ten's place digit.
PUSH AL ; Save the digit for later.
MOV DL, AL
MOV AH, 02H
INT 21H ; Display the ten's place digit.
POP AL ; Fetch the digit.
MOV CL, 10
MUL CL ; Solve for the ten's place value.
MOV DL, RF
SUB DL, AL ; Knock the ten's place value off RF to get the one's place.
MOV AH, 02
INT 21H ; Now display the one's place digit.
JMP DONE
@@:

; Handle all cases of RF = [-9, -1].
CMP RF,-1
JG @F ; jump if greater (signed integer RF > cmp. value)
...
JMP DONE
@@:

; Handle all cases of RF = [0, 9].
CMP RF,9
JA @F ; jump if above (unsigned integer RF > cmp. value)
...
@@:

... (Handle the other cases with similar conditional code.)

DONE:

I write code for Windows, and don't work with interrupts, so I don't know of the registers are preserved through interrupt calls or not, and that's why I preserved and reloaded some register values.  Maybe that code is redundant then.  However, I have had issues with MASM sometimes generating jump displacement values of 0 when I use anonymous labels as conditional jump parameters in place of named labels, so you might want to use named labels instead.

stijohnforever

thnks my group will try to simulate... besides were just beginners thnks again for the help.. hope there's other easy possible ways... thnks :wink

JFG

(That's what happens when I'm in a hurry!)

I forgot to mention the first time that when you take input, you'll want to be able to accomodate values of more than one digit.  To do that, you can add a BYTE variable called Sign, and use the code

MOV C, 0
MOV Sign, 1

GetKey:
MOV AH, 01H
INT 21H
CMP AL, '-'
JNE @F
MOV Sign,-1
JMP GetKey
@@:
CMP AL, ' ' ; Spacebar says we're done.
JE GotDigits
CMP AL, '0' ; Catch keys below the value of '0'.
JB BadKey
CMP AL, '9' ; Catch other keys above the value of '9'.
JA BadKey
SUB AL, '0' ; This is more informative than SUB AL, 30H.
PUSH AL ; Save this value.
MOV AL, 10
MUL C ; Multiply the current value of C by 10.
POP CL ;
ADD AL, CL ; Add the value of the new key.
MOV C, AL ; Put the new value into C.
JMP GetKey ; Get the next key.

BadKey:  ; Handle a bad key case.
...

GotDigits:
CMP Sign, 1
JE GotValue ; If Sign was not left as +1,
NEG C ; make C negative.
GotValue:


Of course, as designed, this code can take input values with any number of digits, so you have to keep in mind that it has an inherent limit because of the data types it uses, although you can still fix that by using larger data types and larger registers in the rest of your program.  I figure you can probably find a way too to modify the output-processing code so it uses a loop for each digit.  Hint:  In that code, you can first do a small loop that counts the number of decimal digits required by multiplying ten by itself over and over, and comparing each new power of ten to RF.  You'll then get a power of ten that is just larger in value than RF.  Then start your output loop using that last power of 10, divided by 10, as your dividing value for knocking off all decimal digits in RF except the highest one.  Dividing each new remainder by successively smaller powers of ten will give you all the smaller digits.

Remember it will always help you to run through your code checking to see exactly what it actually does at each step, rather than just putting it together by coding rules you know.  Take off the comments too when you go through your code, so they don't mislead you by telling you what the code should ideally do rather than just letting you see what it actually does.  Also write down somewhere the values in your variables and in the registers, ideally using a table that shows you how and when they change with execution of each instruction, so you can better keep track of what is going on.  This way you should be able to catch all sorts of bugs that you would not catch otherwise.