c内联汇编char数组为short

时间:2017-05-30 11:08:11

标签: c arrays assembly short chars

我无法让这段代码发挥作用。在调试时,我看到正确的值/地址在寄存器中,但是,当我使用上一个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,并为其他部分保留相同的方法。但是,由于这不起作用,我尝试了许多其他方法(每个方法导致相同的错误),我在这里要求一些清晰度。

2 个答案:

答案 0 :(得分:1)

你有两个问题:

  1. 如何解析字符串。

    如果字符串si始终采用gg/mm/aaaa hh:mm:ss格式,则可以访问具有固定索引的部分。因此,年份可以在指数[6],[7],[8]和[9]中找到。

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

    您可以阅读有关算法的信息。它们并不复杂,只是解释或多或少复杂。在这里,你只有两种数字:两位数字和四位数字。我建议得到值(即整数),就像你向一个小孩子解释一样:一年的价值是[第一位=“数千”] * 1000 + [第二位=“数百”] * 100 + [第三位digit =“tens”] * 10 + [第四位=“单位”]。两位数的值是[第一位=“十位”] * 10 + [第二位=“单位”]。

  3. 另外,我看到了初学者的错误。 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进行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
}