Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Dec to Bin 2

Status
Not open for further replies.

TipGiver

Programmer
Sep 1, 2005
1,863
0
0
Hello,

I want some help on converting a signed dec to bin.
I'll use the div and not the idiv. The registers for the div are:
AH AL / 2 . After this the mod is in the AH and AL has either 0 or 1

How can I know that the entered dec by the keyboard (using the INT 21H, AH=07H) is positive or negative? Let's say that i'll enter a 2-digit dec so min values is -99 and max +99. The problem is that i want to get the number; the user can enter e.g +60 or 60 which are the same.


Thank you in advance for any tip, or any other way to do this
 
Surely the user must be able to specify the sign as well - therefore you would need to allow for three characters to be input.

If the first character is a number then the value is positive and you can report an error if they enter three characters, similarly report an error if the first character is not +, - or a number. Then you will know whether or not the number is negative.

If the first character is "-" then process the number as positive and NEG it.

Hope this helps.

[vampire][bat]
 
By the way, unless you echo the character using function 2, the user will not be able to see what they are typing. Function 1 provides automatic echo.

Hope this helps.

[vampire][bat]
 
I want to allow only 0-9, '+' abd '-'. Is there any jmp to use, so the user should be redirected back a few lines (to a label) to enter again a valid num or one of those signs?

I know the jne dl, 0 (jump if not equal to 0); but how can I use a range of ascii? (0 through 9)?


Thanks for any help
 
Does this bit of pseudocode help?

if ( ( char less than '0' or char greater than '9' ) and
( char not = '+' ) and
( char not = '-' )
) then jmp back to get character in.

How about that?
 
Hi,
I have this code that waits for keypress and then prints the ascii-30h. I mean; i enter only 0 to 9. The asciis are from 30 to 39, so by substracting 30h i get 00 to 09 decimal.


MOV AH,08H ;wait for key
INT 21H

SUB AL,30H ; 00 - 09

MOV AH,02H ; print it
INT 21H

What is wrong here? It do not print.


Tnank you.
 
I had the wrong register. Now it is:

MOV AH,08H
INT 21H

MOV DL,AL
SUB DL,30H

MOV AH,02H
INT 21H


So if i press number 9, its ascii is 39h, minus 30h equals to 9. I wanted-expected to be printed the decimal 9, but what is printed is the char whose ascii is 9... the TAB key?

What i'm missing here?
 
Oddly enough, it's doing exactly what you asked it to do... it prints out ascii.

If you want it to print out the numeric character "9", then you have to load the dl register with 039h...
 
The BIOS will only print characters within its character set based on the ASCII values.

Just to confuse things even more you have the following:

Code:
Diplayed Character   ASCII Code    Keyboard Scan Code*
           0          30H, 48D            11
           1          31H, 49D            02
           2          32H, 50D            03
           3          33H, 51D            04
           4          34H, 52D            05
           5          35H, 53D            06
           6          36H, 54D            07
           7          37H, 55D            08
           8          38H, 56D            09
           9          39H, 57D            10

*The Escape Key has a Scan Code value of 1, and a Scan code of 0, indicates an extended key, for example one of the Function Keys, and that a second Scan Code should be read.

Therefore when you read a character using DOS INT 21H functions 1, 7, 8, 0AH or 3FH (with 0 (STDIN) in BX), the conversion from Keyboard Scan Code to ASCII code has already been done (via a device driver). If you use INT 16H to read the keyboard directly you will get the Keyboard Scan Code and have to translate it yourself.

Essentially, therefore, you read in the characters, convert them to decimal numbers, do any necessary work with the decimal numbers and then convert the result back to ASCII characters for display purposes.

My assembly is very rusty (its been several years since I last did any serious assembly programming), and I don't currently have an assembler installed. However, I've put together a partial program (obviously not tested) to read and convert the numbers as per your original post. If you are interested I will happily post it (although those with current expertise will probably think it very amateurish and amusing [smile])

Hope this helps.

[vampire][bat]
 
Yes earthandfire, i am interested!

This i am currently trying to do with assembly 8086 or x86 is: Enter two decimal digits (digit by digit and not a word). When the second is entered, automatically starts the procedure to convert to binary.
What i had thought of is: Enter 3, then e.g. 4. I meant 34 so i would shift the 3 till it gets 3*10 and add it with 4. But this is not working.
Then i thought of the ascii, to do a substitute with 30h.

I am posting this code. Is any thing wrong here? It is supposed to convert each key i press (0-9) to binary.

.MODEL SMALL
.DATA
.STACK
.CODE
.STARTUP


AGAIN: MOV CX,09H
MOV AH,08H
INT 21H
SUB AL,30H
N3: TEST AL,80H
JNZ N2
MOV AH,02H
INT 21H
N4: SHL AL,01H
LOOP N3
JMP AGAIN
N2: MOV DL,31H
MOV AH,02H
INT 21H
JMP N4

.EXIT 0


Thanks for your help
 
This is my effort no laughing please experts:

Code:
	XOR	BX, BX	;BH = Sign, BL = Digit Count
	XOR	DX, DX	;DH = First Digit, DL = Second Digit
	MOV	AH, 1
	INT	21H
	CMP	AL, 13
	JE	GETOUT
	CMP	AL, "-"
	JNE	CHECKPLUS
	INC	BH
	JMP	SHORT GETNUMBERS
CHECKPLUS:
	CMP	AL, "+"	    ;Just ignore it
	JE	GETNUMBERS
        ;Not a - or + so must have been a number
STOREFIRSTNUMBER:
	CMP	AL, "0"
	JB	GETNUMBERS  ;Not a valid character
	CMP	AL, "9"
	JA	GETNUMBERS  ;not  a valid character
	AND	AL, 47	    ;Or use SUB AL, 48
	MOV	DH, AL
	INC	BL          ;add one to digit count
GETNUMBERS:
	MOV	AH, 1
	INT	21H
	CMP	AL, 13      ;Enter was pressed
	JE	GOTALLDIGITS
	OR	BL, BL      ;if BL is 0 this is 1st number
	JZ	STOREFIRSTNUMBER
	CMP	AL, "0"     ;process 2nd digit as above
	JB	GETNUMBERS
	CMP	AL, "9"
	JA	GETNUMBERS
	AND	AL, 47
	MOV	DL, AL
	INC	BL          ;set BL to 2
GOTALLDIGITS:
	XOR	AL, AL
	CMP	BL, 2       ;if BL = 2 multiply 1st digit by 10
	JNE	LOWDIGIT
	MOV	AL, DH
	MUL	AL, 10
LOWDIGIT:
	ADD	AL, DL
	CMP	BH, 1
	JNE	GOTNUMBER
	NEG	AL
GOTNUMBER:
	;Do whatever you need with the number

GETOUT:
	;All finished

Apologies again for the obviously very rusty code (and since I haven't been able to check this it will probably need to be corrected) but ...

Hope this is of some use.


[vampire][bat]
 
Hi earthandfire.

Yes it need some corrections, like: MUL AL, 10. It MUL source, where source is a register or memory space. It propably needs to store 10 in e.g. SI. Thanks for your efford. I'll propably use some lines of yours.
 
You are partially right about MUL. The "source" determines the destination registers.

MOV SI, 10
MUL SI

would put the result in DX:AX, not good since we are using DX for other purposes. As the result would still be an 8 bit number this means that AH will be 0 (we don't care about that, but DX would also be set to 0). A better alternative based on the registers in my earlier example would probably be:

MOV CL, 10
MUL CL

This would put the result in AX which is what we want.

If I get chance over the weekend I'll install either A86 or MASM and play a bit more.

[vampire][bat]
 
One very good emulator for assembly x86 is here: You can also find it in download.com
I will post again here on this issue.

You deserve a star for your efford
 
Err..

Follow my thought:
By pressing 0 to 9, what i will get is the ascii of those, so 30 to 39 HEX. So I do a SUB with 30H and what's left is 0 to 9 (hex).I'll treat it as decimal (it will contain only 0 to 9). Pressing 3 and 4, say table[0] has 3H and table[1] has 4H.
3 is 0000.0011 and 4 is 0000.0100
What i need to get from these is 0010.0010 which is 34H


Any ideas?
 
This of any use?

Code:
    mov al,39h
    sub al,30h
    mov table1,al

    mov al,32h
    sub al,30h
    mov table2,al

    mov al,table1
    and al,0fh
    mov cl,4
    shl al,cl
    or  al,table2

What you end up with in al is BCD or binary coded decimal.

The upper nibble (bits 4 to 7) holds the most significant digit.

The lower nibble (bits 0 to 3) holds the least significant digit.

It isn't true binary.
 
I finally did something good. Take a look.

Code:
.MODEL SMALL
.DATA
.STACK
.CODE
.STARTUP

       
MOV AH,02H    ; Function to show the ascii of DL
MOV BL,10H    ; My number

MOV CX,08H    ; Loop 8 times (8-bits)

NEXT:   RCL BL,1    ; Rotate left through Carry Flag
        JNC ISZERO
        
        MOV DL,31H  ; 30h is "0"
        JMP DISP
ISZERO: MOV DL,30H  ; 31h is "1"
DISP:   INT 21H     ; Show it
        
LOOP    NEXT        ; Loop until CX=0
     
        
.EXIT 0
 
Thank you.
If i am correct this is... UnPacked BCD?

This: mov cl,4
shl al,cl ,
the shl accepts as shift times a number or cl. It there any reason to do the MOV first?
 
Yup.

the mov cl,4 sets the number of times that the shift left is performed.

Otherwise it'll just shift left the random number of times it happens to find in the cl register.
 
TipGiver, according to MASM documentation, you can only use an immediate constant (other than 1) with the 80186 and above.



[vampire][bat]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top