2017-05-30 52 views
-2

我无法设法使此代码正常工作。在调试时,我看到正确的值/地址在寄存器中,但是,当我使用最后的mov时,它不起作用。c将内联汇编字符数组简写为

我浏览了大量的帖子,但没有找到办法让它工作。因此,基本上,我必须编写一个从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,然后我得到2date[0]al,然后将2放入day

实际上有一些随机数,它们甚至在最后一条指令后都没有改变。我的计划是实际使用任何类型的偏移量连接2之后的0,并为其他部分保留相同的方法。但是,由于这不起作用,并且我尝试了许多其他方法(每个方法导致相同的错误),我在这里要求澄清一些。

+5

[Assembly programming memory memory Allocating EAX vs Ax,AH,AL](https://stackoverflow.com/questions/15191178/assembly-programming-memory-allocating-eax-vs-ax-ah-al) (加**使用调试器**看看,当你做'mov al,date [0]'时,在'eax'中的地址会发生什么) – Ped7g

回答

-1

的代码行:

mov al, date[0] 

应复制日期的值[0] - “2” 到地址。我相信代码应该为:

__asm 
{ 
    lea eax,day 
    mov [al], date[0] 
    mov [eax],al 
} 
+0

如果我试试这个,它会给我错误c2403:寄存器必须是base/index第一个操作数,可悲的是我有一个类似的想法,并得到了同样的错误:( – Cicciopalla010

+0

@ Cicciopalla010你错过了从标记的副本的答案,或者什么东西不清楚? – Ped7g

1

你有两个问题:

  1. 如何解析字符串。

    如果字符串si始终为格式gg/mm/aaaa hh:mm:ss,则可以访问其固定索引的零件。所以这一年可以在指数[6],[7],[8]和[9]中找到。

  2. 如何将字符串转换为整数。

    您可以阅读有关算法。它们并不复杂,只是解释更复杂或更简单。在这里,你只有两种数字:两位数字和四位数字。我建议你得到这个值(即整数),就像你给一个小孩解释一样:一年的价值是[first digits =“thousand”] * 1000 + [second digit =“hundred”] * 100 + [third数字=“十”] * 10 + [第四位=“单位”]。两位数字的值是[第一位=“十”] * 10 + [第二位=“单位”]。

此外,我看到一个初学者的错误。 ALAX的一部分,是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进行与运算 - 它们变为0.最后4位与1111(F)进行与运算 - 它们保持其原始状态。 0x35 AND 0x0F = 0x05。当你看到任何地方减48或0x30 - 这追求相同的目的。

+0

ty ty ty是啊我只是一个初学者和即时还挺有点挣扎,因为我我只用c#C++编程,而c之前至少意味着我没有真正与堆栈等工作很多... id问“如何”和al,0fh“工程来隔离十进制数? – Cicciopalla010

+0

@ Cicciopalla010:I添加了解释国家的答案。我希望这有点可以理解;-) – rkhb