我无法让这段代码发挥作用。在调试时,我看到正确的值/地址在寄存器中,但是,当我使用上一个mov
时,它仍然不起作用。
我浏览了大量帖子,但没有找到办法让它发挥作用。因此,基本上,我必须编写一个从char
数组中取出的日期,并将日期的每个部分放在相应的变量中。尽管如此,我还是不完全了解大会如何运作,我很乐意得到一些帮助。
这是我的代码:
#include <stdio.h>
void main()
{
// 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
{
lea eax,day
mov al, date[0]
mov [eax],al
}
// 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();
}
我可能错了,但是那里的汇编代码部分应该放入eax
day
的地址/引用,然后我从2
获取date[0]
al
然后将2
放入day
。
实际上有一些随机数,在最后一条指令后它们甚至没有改变。我的计划是实际使用任何类型的偏移量来连接0
之后的2
,并为其他部分保留相同的方法。但是,由于这不起作用,我尝试了许多其他方法(每个方法导致相同的错误),我在这里要求一些清晰度。
答案 0 :(得分:1)
你有两个问题:
如何解析字符串。
如果字符串si始终采用gg/mm/aaaa hh:mm:ss
格式,则可以访问具有固定索引的部分。因此,年份可以在指数[6],[7],[8]和[9]中找到。
如何将字符串转换为整数。
您可以阅读有关算法的信息。它们并不复杂,只是解释或多或少复杂。在这里,你只有两种数字:两位数字和四位数字。我建议得到值(即整数),就像你向一个小孩子解释一样:一年的价值是[第一位=“数千”] * 1000 + [第二位=“数百”] * 100 + [第三位digit =“tens”] * 10 + [第四位=“单位”]。两位数的值是[第一位=“十位”] * 10 + [第二位=“单位”]。
另外,我看到了初学者的错误。 AL
是AX
的一部分,是EAX
的一部分。如果您更改AL
(例如mov al, date[0]
),则也会更改EAX
。
#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;
}
从ASCII字符中隔离可计算的数字。当您从字符串中获取数字时,您将获得ASCII字符,例如“20”是0x32和0x30。对于像2 * 10 + 0这样的算术,你需要“裸”十进制数。 ASCII数字位于0x30和0x39之间的表中。如果您可以删除该十六进制数中的第一个“3”,则会得到计算机可以计算的数字。这是AND 0Fh
的目的。前4位与0000进行AND运算 - 它们变为0.最后4位与1111(F)进行AND运算 - 它们保持原始状态。 0x35 AND 0x0F = 0x05
。当你看到减去48或0x30的任何地方时 - 这就是出于同样的目的。
答案 1 :(得分:-1)
代码行:
mov al, date[0]
应该复制date [0] - &#34; 2&#34;进入地址。我相信代码应该是:
__asm
{
lea eax,day
mov [al], date[0]
mov [eax],al
}