Assembly x86 Date to Number - Breaking a string into smaller sections -
i'm looking pointed in right direction on issue.
i'm looking convert date in x86 assembly format "dd-mmm-yyyy" unique number can bubble sorted later , converted back.
so, when have string input ie: .data indate dw "08-sep-1993"
and want split to
day = "08" month = "sep" year = "1993" so can process further (i'll converting sep "7", ect.)
so question simple, efficient way break date down (code-wise)? know i'll need convert date format allow sorting, i'm new assembly i'm not positive how break string can convert it.
also, second question, how convert number string actual numerical value?
thanks!
note: suppose should noted i'm using masm32
next little program made emu8086 (16 bits), captures numbers keyboard strings, convert them numeric compare, , converts number string display. notice numbers captured 0ah, requieres 3-level variable "str". conversion procedures need @ bottom of code (string2number , number2string).
.model small .stack 100h .data counter dw ? msj1 db 'enter number: $' msj2 db 'the highest number is: $' break db 13,10,'$' str db 6 ;max number of characters allowed (4). db ? ;number of characters entered user. db 6 dup (?) ;characters entered user. highest dw 0 buffer db 6 dup(?) .code ;initialize data segment. mov ax, @data mov ds, ax ;----------------------------------------- ;capture 5 numbers , determine highest. mov counter, 5 ;how many numbers capture. enter_numbers: ;display message. mov dx, offset msj1 call printf ;capture number string. mov dx, offset str call scanf ;display line break. mov dx, offset break call printf ;convert captured number string numeric. mov si, offset str ;parameter (string convert). call string2number ;number returns in bx. ;check if captured number highest. cmp highest, bx jae ignore ;if (highest >= bx) ignore number. ;if no jump "ignore", current number higher "highest". mov highest, bx ;current number highest. ignore: ;check if have captured 5 numbers already. dec counter jnz enter_numbers ;----------------------------------------- ;display highest number. ;first, fill buffer '$' (necessary display). mov si, offset buffer call dollars ;second, convert highest number string. mov ax, highest mov si, offset buffer call number2string ;third, display string. mov dx, offset msj2 call printf mov dx, offset buffer call printf ;finish program. mov ax, 4c00h int 21h ;----------------------------------------- ;parameter : dx pointing '$' finished string. proc printf mov ah, 9 int 21h ret endp ;----------------------------------------- ;parameter : dx pointing buffer store string. proc scanf mov ah, 0ah int 21h ret endp ;------------------------------------------ ;convert string number. ;parameter : si pointing captured string. ;return : number in bx. proc string2number ;make si point least significant digit. inc si ;points number of characters entered. mov cl, [ si ] ;number of characters entered. mov ch, 0 ;clear ch, cx==cl. add si, cx ;now si points least significant digit. ;convert string. mov bx, 0 mov bp, 1 ;multiple of 10 multiply every digit. repeat: ;convert character. mov al, [ si ] ;character process. sub al, 48 ;convert ascii character digit. mov ah, 0 ;clear ah, ax==al. mul bp ;ax*bp = dx:ax. add bx, ax ;add result 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 have finished. dec si ;next digit process. loop repeat ;counter cx-1, if not zero, repeat. ret endp ;------------------------------------------ ;fills variable '$'. ;used before convert numbers string, because ;the string displayed. ;parameter : si = pointing string fill. proc dollars mov cx, 6 six_dollars: mov bl, '$' mov [ si ], bl inc si loop six_dollars ret endp ;------------------------------------------ ;convert number in string. ;algorithm : extract digits 1 one, store ;them in stack, extract them in reverse ;order construct string (str). ;parameters : ax = number convert. ; si = pointing store string. proc number2string mov bx, 10 ;digits extracted dividing 10. mov cx, 0 ;counter extracted digits. cycle1: mov dx, 0 ;necessary divide bx. div bx ;dx:ax / 10 = ax:quotient dx:remainder. push dx ;preserve digit extracted later. inc cx ;increase counter every digit extracted. cmp ax, 0 ;if number jne cycle1 ;not zero, loop. ;now retrieve pushed digits. cycle2: pop dx add dl, 48 ;convert digit character. mov [ si ], dl inc si loop cycle2 ret endp now 32 bits version. next little program assigns eax big number, convert string , convert numeric, here is:
.model small .586 .stack 100h .data msj1 db 13,10,'original eax = $' msj2 db 13,10,'flipped eax = $' msj3 db 13,10,'new eax = $' buf db 11 db ? db 11 dup (?) .code start: ;initialize data segment. mov ax, @data mov ds, ax ;convert eax string display it. call dollars ;necessary display. mov eax, 1234567890 call number2string ;parameter:ax. return:variable buf. ;display 'original eax'. mov ah, 9 mov dx, offset msj1 int 21h ;display buf (eax converted string). mov ah, 9 mov dx, offset buf int 21h ;flip eax. call dollars ;necessary display. mov eax, 1234567890 call flip_eax ;parameter:ax. return:variable buf. ;display 'flipped eax'. mov ah, 9 mov dx, offset msj2 int 21h ;display buf (eax flipped converted string). mov ah, 9 mov dx, offset buf int 21h ;convert string number (flipped eax eax). mov si, offset buf ;string reverse. call string2number ;return in ebx. mov eax, ebx ;this new eax flipped. ;convert eax string display it. call dollars ;necessary display. call number2string ;parameter:eax. return:variable buf. ;display 'new eax'. mov ah, 9 mov dx, offset msj3 int 21h ;display buf (eax converted string). mov ah, 9 mov dx, offset buf int 21h ;wait until user press key. mov ah, 7 int 21h ;finish program. mov ax, 4c00h int 21h ;------------------------------------------ flip_eax proc mov si, offset buf ;digits stored in buf. mov bx, 10 ;digits extracted dividing 10. mov cx, 0 ;counter extracted digits. extracting: ;extract 1 digit. mov edx, 0 ;necessary divide ebx. div ebx ;edx:eax / 10 = eax:quotient edx:remainder. ;insert digit in string. add dl, 48 ;convert digit character. mov [ si ], dl inc si ;next digit. cmp eax, 0 ;if number jne extracting ;not zero, repeat. ret flip_eax endp ;------------------------------------------ ;convert string number in ebx. ;si must enter pointing string. string2number proc ;count digits in string. mov cx, 0 find_dollar: inc cx ;digit counter. inc si ;next character. mov bl, [ si ] cmp bl, '$' jne find_dollar ;if bl != '$' jump. dec si ;because on '$', not on last digit. ;convert string. mov ebx, 0 mov ebp, 1 ;multiple of 10 multiply every digit. repeat: ;convert character. mov eax, 0 ;now eax==al. mov al, [ si ] ;character process. sub al, 48 ;convert ascii character digit. mul ebp ;eax*ebp = edx:eax. add ebx, eax ;add result bx. ;increase multiple of 10 (1, 10, 100...). mov eax, ebp mov ebp, 10 mul ebp ;ax*10 = edx:eax. mov ebp, eax ;new multiple of 10. ;check if have finished. dec si ;next digit process. loop repeat ;cx-1, if not zero, repeat. ret string2number endp ;------------------------------------------ ;fills variable str '$'. ;used before convert numbers string, because ;the string displayed. dollars proc mov si, offset buf mov cx, 11 six_dollars: mov bl, '$' mov [ si ], bl inc si loop six_dollars ret dollars endp ;------------------------------------------ ;number convert must enter in eax. ;algorithm : extract digits 1 one, store ;them in stack, extract them in reverse ;order construct string (buf). number2string proc mov ebx, 10 ;digits extracted dividing 10. mov cx, 0 ;counter extracted digits. cycle1: mov edx, 0 ;necessary divide ebx. div ebx ;edx:eax / 10 = eax:quotient edx:remainder. push dx ;preserve digit extracted (dl) later. inc cx ;increase counter every digit extracted. cmp eax, 0 ;if number jne cycle1 ;not zero, loop. ;now retrieve pushed digits. mov si, offset buf cycle2: pop dx add dl, 48 ;convert digit character. mov [ si ], dl inc si loop cycle2 ret number2string endp end start
Comments
Post a Comment