instruction string assembly x86 masm32

string - instruction assembly



Ensamblado x86 Fecha a número: división de una cadena en secciones más pequeñas (1)

El siguiente pequeño programa se realizó con EMU8086 (16 bits), captura los números del teclado como cadenas, los convierte en numéricos para comparar y finalmente convierte un número en una cadena para mostrar. Observe que los números se capturan con 0AH, lo que requiere una variable "str" ​​de 3 niveles. Los procedimientos de conversión que necesita están en la parte inferior del código ( string2number y 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

Ahora la versión de 32 bits . El siguiente es un pequeño programa que asigna a EAX un gran número, lo convierte en cadena y lo vuelve a convertir en numérico, aquí está:

.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

De hecho, estoy buscando que se apunte en la dirección correcta en un tema.

Estoy buscando convertir una fecha en Asamblea x86 del formato "DD-MMM-AAAA" a un número único para que se pueda clasificar por burbujas más tarde y eventualmente volver a convertir.

Entonces, cuando tengo una entrada de cadena, es decir: .data inDate dw "08-SEP-1993"

Y quiero dividirlo en

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

Para poder seguir procesándolo (convertiré SEP a "7", etc.)

Entonces, mi pregunta es ¿cuál es una manera simple y eficiente de desglosar la fecha (en cuanto al código)? Sé que tendré que convertir el formato de fecha para permitir la clasificación, pero soy nuevo en Assembly, así que no estoy seguro de cómo dividir la cadena para poder convertirla.

Además, como segunda pregunta, ¿cómo convertiría un número de la cadena en un valor numérico real?

¡Gracias!

NOTA: supongo que debe tenerse en cuenta que estoy usando masm32