You've got two problems:
How to parse a string.
If the string si always in the format gg/mm/aaaa hh:mm:ss
you can access to its parts with fixed indices. So the year can be found at the indices [6], [7], [8], and [9].
How to convert a string into an integer.
You can read about the algorithms. They are not complicated, just explained more or less complicated. Here, you've got just two kinds of numbers: those with two digits and those with four digits. I suggest to get the value (i.e. integer) as you would explain it to a little child: The value of a year is [first digit = "thousands"]*1000 + [second digit = "hundreds"]*100 + [third digit = "tens"]*10 + [fourth digit = "units"]. The value of a two-digit-number is [first digit = "tens"]*10 + [second digit = "units"].
Additionally, I see a beginner's mistake. AL
is a part of AX
is a part of EAX
. If you change AL
(e.g. mov al, date[0]
), you change EAX
as well.
#include <stdio.h>
int main ( void )
{
// Input
char date[] = "20/06/1999 13:23:47"; //gg/mm/aaaa hh:mm:ss
// Output
unsigned short day;
unsigned short month;
unsigned short year;
unsigned short hour;
unsigned short minute;
unsigned short second;
__asm
{
mov cl, 10 ; Multiplicator
mov al, date[0] ; First digit
and al, 0Fh ; Isolate the decimal number of the ASCII character
mul cl ; AX = AL * CL => tens
mov dl, date[1] ; Second digit
and dx, 0Fh ; Isolate the decimal number of the ASCII character
add ax, dx ; Add the tens and the units
mov [day],ax ; Save the result
mov al, date[3] ; First digit
and al, 0Fh ; Isolate the decimal number of the ASCII character
mul cl ; AX = AL * CL
mov dl, date[4] ; Second digit
and dx, 0Fh ; Isolate the decimal number of the ASCII character
add ax, dx ; Add the tens and the units
mov [month],ax ; Save the result
movzx ax, byte ptr date[6] ; Load one byte into a word register
and al, 0Fh ; Isolate the decimal number of the ASCII character
imul dx, ax, 1000 ; DX = AX * 1000 => millenium
movzx ax, byte ptr date[7] ; Load one byte into a word register
and al, 0Fh ; Isolate the decimal number of the ASCII character
imul ax, ax, 100 ; AX = AX * 100
add dx, ax ; Add it to the millenium => 1900
movzx ax, byte ptr date[8] ; Load one byte into a word register
and al, 0Fh ; Isolate the decimal number of the ASCII character
imul ax, ax, 10
add dx, ax ; Add it => 1990
movzx ax, byte ptr date[9] ; Load one byte into a word register
and al, 0Fh ; Isolate the decimal number of the ASCII character
add dx, ax ; Add it => 1999
mov [year], dx ; Save the result (DX!)
mov al, date[11] ; First digit
and al, 0Fh ; Isolate the decimal number of the ASCII character
mul cl ; AX = AL * CL
mov dl, date[12] ; Second digit
and dx, 0Fh ; Isolate the decimal number of the ASCII character
add ax, dx ; Add the tens and the units
mov [hour], ax ; Save the result
mov al, date[14] ; First digit
and al, 0Fh ; Isolate the decimal number of the ASCII character
mul cl ; AX = AL * CL
mov dl, date[15] ; Second digit
and dx, 0Fh ; Isolate the decimal number of the ASCII character
add ax, dx ; Add the tens and the units
mov [minute],ax ; Save the result
mov al, date[17] ; First digit
and al, 0Fh ; Isolate the decimal number of the ASCII character
mul cl ; AX = AL * CL
mov dl, date[18] ; Second digit
and dx, 0Fh ; Isolate the decimal number of the ASCII character
add ax, dx ; Add the tens and the units
mov [second],ax ; Save the result
}
// Stampa su video
printf("day: %i month: %i year: %i hour: %i minute: %i second: %i \n", day,month,year,hour, minute, second);
// printf("press a key to go");
// getchar();
return 0;
}
Isolating a calculable number from an ASCII character. When you fetch a number from a string you get ASCII characters, e.g "20" is 0x32 and 0x30. For arithmetics like 2 * 10 + 0 you need the "bare" decimal number. The ASCII digits resides in the table between 0x30 and 0x39. If you can get rid of the first "3" in that hexadecimal number you get a number that the computer can calculate. This is the purpose of the AND 0Fh
. The first 4 bits are ANDed by 0000 - they become 0. The last 4 bits are ANDed by 1111 (F) - they keep their original state. 0x35 AND 0x0F = 0x05
. When you see anywhere a subtraction by 48 or 0x30 - this pursues the same purpose.