ok, i cant seem to convert a group of ascii valuse to a integer.this is the code i have so far and it doesnt seem to work. i am using masm615. any code/ help would be great.
parseInt PROC;
push Bx ; push all of the registers so none are corrupted
push SI ;
push CX ;
mov DI, 0h ;
MOV bX, si ; get addy to place string
mov si, 10 ; 10 for the multiplication
again:
cmp byte ptr [bx], 48 ; is it a null
jz done ;
cmp byte ptr [bx], 48 ; is it less then 0
JLE next ;
cmp byte ptr [bx], 57 ; is it greater then 9
JGE next ;
sub byte ptr [bx], 30h ; make a number
mov ax, [bx] ; get the value into ax so it can multiply
mul si ; multiply
inc bx ; go to next char in bx
push bx
sub byte ptr [bx], 30h ;
add ax, [bx] ; add dx and bx to get the new number
pop bx
dec cx ; count one less
cmp cx, 0h ;
jnz again ; if count is not zero go again
jmp done ; if it is zero, end
next:
inc bx ;
jmp again ;
done:
mov ax, [bx] ; mov the addy of bx into ax
pop CX ;
pop SI ; pops all the registers
pop BX ;
Comments
mov si, di ;
call parseInt ;
mov si, ax ; echos the string typed in
mov al, 1 ;
call intOut ;
parseInt PROC
push Bx ; push all of the registers so none are corrupted
push SI ;
push CX ;
mov DI, 0h ;
MOV bX, si ; get addy to place string
mov si, 10 ; 10 for the multiplication
again:
cmp byte ptr [bx], '0' ; is it a null
jz done ;
cmp byte ptr [bx], 48 ; is it less then 0
JLE next ;
cmp byte ptr [bx], 57 ; is it greater then 9
JGE next ;
sub byte ptr [bx], '0' ; make a number
mov ax, [bx] ; get the value into ax so it can multiply
mul si ; multiply
inc bx ; go to next char in bx
push bx
sub byte ptr [bx], '0' ;
add ax, [bx] ; add dx and bx to get the new number
pop bx
dec cx ; count one less
cmp cx, 0h ;
jnz again ; if count is not zero go again
jmp done ; if it is zero, end
next:
inc bx ;
jmp again ;
done:
mov ax, [bx] ; mov the addy of bx into ax
pop CX ;
pop SI ; pops all the registers
pop BX ;
ret
parseInt ENDP
intOut PROC
mov cx, 10 ;divide by
mov ax, si
again:
mov dx, 0 ; puting 0 in the high part of the divided number (DX:AX)
div cx ;
add dl, '0' ;
mov bx, ax
mov ah, 2 ; print char interupt
int 21h
mov ax, bx
cmp ax, 0
jne again
ret
intOut ENDP
NERD FOR LIFE
I Hate ID10T User Errors
[blue]I see at least two problems - see RED... there may be more, but try it and see if it works. On my site I have some code samples for the conversion: www.codexxi.com
[/blue]
[code]
:
: mov si, di ;
: call parseInt ;
:
: mov si, ax ; echos the string typed in
: mov al, 1 ;
: call intOut ;
:
:
:
:
: parseInt PROC
:
: push Bx ; push all of the registers so none are corrupted
: push SI ;
: push CX ;
: mov DI, 0h ;
: MOV bX, si ; get addy to place string
: mov si, 10 ; 10 for the multiplication
:
: again:
: cmp byte ptr [bx], '0' ; is it a null
: jz done ;
: cmp byte ptr [bx], 48 ; is it less then 0
: JLE next ;
: cmp byte ptr [bx], 57 ; is it greater then 9
: JGE next ;
: sub byte ptr [bx], '0' ; make a number
: mov ax, [bx] ; get the value into ax so it
; can multiply
[red][b]
Here ^^^ you load the WORD at address in BX, yet before
you were working with a BYTE. You have to load a BYTE into
AL and clear AH to zero, so full AX will be loaded correctly.
Here is the code which can do it:
MOV AL, [BX]
CBW
[/b][/red]
: mul si ; multiply
: inc bx ; go to next char in bx
: push bx
: sub byte ptr [bx], '0' ;
: add ax, [bx] ; add dx and bx to get the new number
: pop bx
: dec cx ; count one less
: cmp cx, 0h ;
: jnz again ; if count is not zero go again
: jmp done ; if it is zero, end
:
: next:
: inc bx ;
: jmp again ;
:
: done:
: mov ax, [bx] ; mov the addy of bx into ax
: pop CX ;
: pop SI ; pops all the registers
: pop BX ;
:
: ret
: parseInt ENDP
:
: intOut PROC
:
: mov cx, 10 ;divide by
: mov ax, si
: again:
: mov dx, 0 ; puting 0 in the high part of
; the divided number (DX:AX)
: div cx ;
: add dl, '0' ;
: mov bx, ax
: mov ah, 2 ; print char interupt
: int 21h
: mov ax, bx
: cmp ax, 0
: jne again
:
[red][b]
This procedure prints digits from division by 10, but you need them
backwards. Here is a small sample: say, you have a value 1234. Here is
what you will get:
1234/10 = 123 and '4' printed
123/10 = 12 and '3' printed
12/10 = 1 and '2' printed
1/10 = 0 and '1' printed
So, the printed text will be "4321".
Prepare an array in memory and point some register at the end of it.
After division - save your digits into that address moving the address
backwards, so the value will be stored in opposite order. Then print
it on one shot with a function AH=9 (INT 21H).
strValue db 'xxxxx$'
...
MOV DI, OFFSET [strValue+5] ; That points DI at '$'
...
DEC DI
MOV [DI], BL ; Saving a digit
...
MOV DX, DI
MOV AH, 9
INT 21H ; printing whole string
[/b][/red]
: ret
: intOut ENDP
[/code]
: NERD FOR LIFE
:
: I Hate ID10T User Errors
:
:
NERD FOR LIFE
I Hate ID10T User Errors
: NERD FOR LIFE
:
: I Hate ID10T User Errors
:
:
[blue]Try to use debugger on your code - did you try it? I will try your code now in debugger and maybe it will help... but I have TASM - hope it is no problem.[/blue]
: NERD FOR LIFE
:
: I Hate ID10T User Errors
:
:
[blue]Here you go... the COM file (my favourite)[/blue]
[code]
.model tiny ; asmguru62 (making a COM file)
.code ; asmguru62 (code section begins)
org 100h ; asmguru62 (making a COM file)
;;;;;;; asmguru62 (program begins here)
main:
call get_user_input
mov di, offset [input_buffer] ; prepare for the next statement
; The original posted code begins here!
mov si, di ;
call parseInt ; The result is in AX after this call
; check if the error was produced?
cmp byte ptr [error_flag], 1
je err_msg
mov si, ax ; echos the string typed in
mov al, 1 ;
call intOut ;
mov ax, 4C00h ; asmguru62 (quit back to DOS)
int 21h
err_msg:
mov dx, offset [strErrMsg]
mov ah, 9
int 21h
jmp main
parseInt PROC
mov byte ptr [error_flag], 0 ; Clear out the error flag
push Bx ; push all of the registers so none are corrupted
push SI ;
push DI ;
mov DI, 0h ; I assume that is where the result is (why it is never used?)
MOV bX, si ; get addy to place string
mov si, 10 ; 10 for the multiplication
again:
cmp byte ptr [bx], 0Dh ; is it a terminator from input?
jz done ; Yes. Terminated. Gone. Asta la vista!
; Check if that is a digit or not?
cmp byte ptr [bx], '0' ; is it less then 0
JB error ; [ J ]ump If [ B ]elow '0'
cmp byte ptr [bx], '9' ; is it greater then 9
JA error ; [ J ]ump If [ A ]bove '9'
; It is a valid digit!
sub byte ptr [bx], '0' ; make a binary number
jmp convert
error:
inc error_flag ; Going from 0 to 1
jmp done ; Bail on error...
convert:
mov al, [bx] ; get the value into AX so it can multiply
cbw
; Here we need this: DI = DI*10 + AX
push ax
mov ax, di
mul si
mov di, ax
pop ax
add di, ax ; Done! Result is back in DI
; next character
inc bx ;
jmp again ;
done:
mov ax, di ; mov the result into ax
pop DI ;
pop SI ; pops all used registers
pop BX ;
ret
parseInt ENDP
intOut PROC ; Looks like SI is a value to work with
; ^^^ When doing procedures - always comment on what are the params
mov cx, 10 ;divide by
mov ax, si
mov bx, offset [out_buffer+5] ; end of buffer
again2:
mov dx, 0 ; puting 0 in the high part of the divided number (DX:AX)
div cx ;
add dl, '0' ;
; put the digit into a buffer
dec bx
mov [bx], dl
cmp ax, 0
jne again2
; dump the string to console
mov dx, offset [str_result]
mov ah, 9
int 21h
mov dx, bx
mov ah, 9
int 21h
ret
intOut ENDP
get_user_input Proc ;;;; asmguru62 (new function to enter text)
mov dx, offset [str_prompt]
mov ah, 9
int 21h
mov dx, offset [max_chars]
mov ah, 0Ah ; Good one! :-)
int 21h ; This will put text from console into 'input_buffer'
ret
get_user_input EndP
; asmguru62 (variables defined here...)
max_chars db 6 ; Allow 5 chars + ENTER
num_chars db 0
input_buffer db 8 dup (0) ; Entered text is here terminated by 0Dh
str_prompt db 'Please, enter the value: $'
str_result db 0Dh,0Ah,'Your value was: $'
strErrMsg db 0Dh,0Ah,'Non-digit was entered. Please, try again...',0Dh,0Ah,'$'
out_buffer db 'xxxxx$'
error_flag db 0
; asmguru62 (variables ended)
end main ; asmguru62 (marking the last statement)
[/code]