Assemblaggio x86 Data a numero – Rompere una stringa in sezioni più piccole

In realtà sto cercando di essere indicato nella giusta direzione su un problema.

Sto cercando di convertire una data in Assembly x86 dal formato “DD-MMM-YYYY” in un numero univoco in modo che possa essere smistata in seguito e convertita alla fine.

Quindi, quando ho una stringa di input, cioè: .data inDate dw “08-SEP-1993”

E voglio dividerlo in

day = "08" month = "SEP" year = "1993" 

Così posso elaborarlo ulteriormente (convertirò SEP in “7”, ecc.)

Quindi la mia domanda è che cosa è un modo semplice ed efficace per spezzare la data (in termini di codice)? So che ho bisogno di convertire il formato della data per consentire l’ordinamento, ma sono nuovo di Assembly quindi non sono sicuro di come rompere la stringa in modo da poterlo convertire.

Inoltre, come seconda domanda, come convertire un numero dalla stringa in un valore numerico effettivo?

Grazie!

NOTA: Suppongo che si noti che sto usando masm32

Il prossimo piccolo programma è stato realizzato con EMU8086 (16 bit), cattura numeri da tastiera come stringhe, li converte in numeri per confrontare e infine converte un numero in stringa da visualizzare. Si noti che i numeri vengono catturati con 0AH, che richiede una variabile “str” ​​di 3 livelli. Le procedure di conversione necessarie sono nella parte inferiore del codice ( string2number e number2string ).

 .model small .stack 100h .data counter dw ? msj1 db 'Enter a 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 BY USER. db 6 dup (?) ;CHARACTERS ENTERED BY USER. highest dw 0 buffer db 6 dup(?) .code ;INITIALIZE DATA SEGMENT. mov ax, @data mov ds, ax ;----------------------------------------- ;CAPTURE 5 NUMBERS AND DETERMINE THE HIGHEST. mov counter, 5 ;HOW MANY NUMBERS TO CAPTURE. enter_numbers: ;DISPLAY MESSAGE. mov dx, offset msj1 call printf ;CAPTURE NUMBER AS STRING. mov dx, offset str call scanf ;DISPLAY LINE BREAK. mov dx, offset break call printf ;CONVERT CAPTURED NUMBER FROM STRING TO NUMERIC. mov si, offset str ;PARAMETER (STRING TO CONVERT). call string2number ;NUMBER RETURNS IN BX. ;CHECK IF CAPTURED NUMBER IS THE HIGHEST. cmp highest, bx jae ignore ;IF (HIGHEST >= BX) IGNORE NUMBER. ;IF NO JUMP TO "IGNORE", CURRENT NUMBER IS HIGHER THAN "HIGHEST". mov highest, bx ;CURRENT NUMBER IS THE HIGHEST. ignore: ;CHECK IF WE HAVE CAPTURED 5 NUMBERS ALREADY. dec counter jnz enter_numbers ;----------------------------------------- ;DISPLAY HIGHEST NUMBER. ;FIRST, FILL BUFFER WITH '$' (NECESSARY TO DISPLAY). mov si, offset buffer call dollars ;SECOND, CONVERT HIGHEST NUMBER TO 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 TO '$' FINISHED STRING. proc printf mov ah, 9 int 21h ret endp ;----------------------------------------- ;PARAMETER : DX POINTING TO BUFFER TO STORE STRING. proc scanf mov ah, 0Ah int 21h ret endp ;------------------------------------------ ;CONVERT STRING TO NUMBER. ;PARAMETER : SI POINTING TO CAPTURED STRING. ;RETURN : NUMBER IN BX. proc string2number ;MAKE SI TO POINT TO THE LEAST SIGNIFICANT DIGIT. inc si ;POINTS TO THE NUMBER OF CHARACTERS ENTERED. mov cl, [ si ] ;NUMBER OF CHARACTERS ENTERED. mov ch, 0 ;CLEAR CH, NOW CX==CL. add si, cx ;NOW SI POINTS TO LEAST SIGNIFICANT DIGIT. ;CONVERT STRING. mov bx, 0 mov bp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT. repeat: ;CONVERT CHARACTER. mov al, [ si ] ;CHARACTER TO PROCESS. sub al, 48 ;CONVERT ASCII CHARACTER TO DIGIT. mov ah, 0 ;CLEAR AH, NOW AX==AL. mul bp ;AX*BP = DX:AX. add bx, ax ;ADD RESULT TO 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 WE HAVE FINISHED. dec si ;NEXT DIGIT TO PROCESS. loop repeat ;COUNTER CX-1, IF NOT ZERO, REPEAT. ret endp ;------------------------------------------ ;FILLS VARIABLE WITH '$'. ;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE ;THE STRING WILL BE DISPLAYED. ;PARAMETER : SI = POINTING TO STRING TO FILL. proc dollars mov cx, 6 six_dollars: mov bl, '$' mov [ si ], bl inc si loop six_dollars ret endp ;------------------------------------------ ;CONVERT A NUMBER IN STRING. ;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE ;THEM IN STACK, THEN EXTRACT THEM IN REVERSE ;ORDER TO CONSTRUCT STRING (STR). ;PARAMETERS : AX = NUMBER TO CONVERT. ; SI = POINTING WHERE TO STORE STRING. proc number2string mov bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10. mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS. cycle1: mov dx, 0 ;NECESSARY TO DIVIDE BY BX. div bx ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER. push dx ;PRESERVE DIGIT EXTRACTED FOR LATER. inc cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED. cmp ax, 0 ;IF NUMBER IS jne cycle1 ;NOT ZERO, LOOP. ;NOW RETRIEVE PUSHED DIGITS. cycle2: pop dx add dl, 48 ;CONVERT DIGIT TO CHARACTER. mov [ si ], dl inc si loop cycle2 ret endp 

Ora la versione a 32 bit . Next è un piccolo programma che assegna a EAX un grande numero, lo converte in stringa e lo converte in numerico, eccolo qui:

 .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 TO STRING TO DISPLAY IT. call dollars ;NECESSARY TO 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 TO STRING). mov ah, 9 mov dx, offset buf int 21h ;FLIP EAX. call dollars ;NECESSARY TO 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 TO STRING). mov ah, 9 mov dx, offset buf int 21h ;CONVERT STRING TO NUMBER (FLIPPED EAX TO EAX). mov si, offset buf ;STRING TO REVERSE. call string2number ;RETURN IN EBX. mov eax, ebx ;THIS IS THE NEW EAX FLIPPED. ;CONVERT EAX TO STRING TO DISPLAY IT. call dollars ;NECESSARY TO DISPLAY. call number2string ;PARAMETER:EAX. RETURN:VARIABLE BUF. ;DISPLAY 'NEW EAX'. mov ah, 9 mov dx, offset msj3 int 21h ;DISPLAY BUF (EAX CONVERTED TO STRING). mov ah, 9 mov dx, offset buf int 21h ;WAIT UNTIL USER PRESS ANY KEY. mov ah, 7 int 21h ;FINISH PROGRAM. mov ax, 4c00h int 21h ;------------------------------------------ flip_eax proc mov si, offset buf ;DIGITS WILL BE STORED IN BUF. mov bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10. mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS. extracting: ;EXTRACT ONE DIGIT. mov edx, 0 ;NECESSARY TO DIVIDE BY EBX. div ebx ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER. ;INSERT DIGIT IN STRING. add dl, 48 ;CONVERT DIGIT TO CHARACTER. mov [ si ], dl inc si ;NEXT DIGIT. cmp eax, 0 ;IF NUMBER IS jne extracting ;NOT ZERO, REPEAT. ret flip_eax endp ;------------------------------------------ ;CONVERT STRING TO NUMBER IN EBX. ;SI MUST ENTER POINTING TO THE 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 IT WAS OVER '$', NOT OVER THE LAST DIGIT. ;CONVERT STRING. mov ebx, 0 mov ebp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT. repeat: ;CONVERT CHARACTER. mov eax, 0 ;NOW EAX==AL. mov al, [ si ] ;CHARACTER TO PROCESS. sub al, 48 ;CONVERT ASCII CHARACTER TO DIGIT. mul ebp ;EAX*EBP = EDX:EAX. add ebx, eax ;ADD RESULT TO 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 WE HAVE FINISHED. dec si ;NEXT DIGIT TO PROCESS. loop repeat ;CX-1, IF NOT ZERO, REPEAT. ret string2number endp ;------------------------------------------ ;FILLS VARIABLE STR WITH '$'. ;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE ;THE STRING WILL BE 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 TO CONVERT MUST ENTER IN EAX. ;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE ;THEM IN STACK, THEN EXTRACT THEM IN REVERSE ;ORDER TO CONSTRUCT STRING (BUF). number2string proc mov ebx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10. mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS. cycle1: mov edx, 0 ;NECESSARY TO DIVIDE BY EBX. div ebx ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER. push dx ;PRESERVE DIGIT EXTRACTED (DL) FOR LATER. inc cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED. cmp eax, 0 ;IF NUMBER IS jne cycle1 ;NOT ZERO, LOOP. ;NOW RETRIEVE PUSHED DIGITS. mov si, offset buf cycle2: pop dx add dl, 48 ;CONVERT DIGIT TO CHARACTER. mov [ si ], dl inc si loop cycle2 ret number2string endp end start