我有一个用C编写的代码,其中主要的tak是用Assembly编写的。编程的想法是,例如,当x = abc def,而y = a时,它将删除至少一个字母相同的单词,并写入不包含相同字母的单词,从而将其写入def。我写了一个代码,但它给出了如下错误:


节目:10:错误:没有这样的指令:`addl $ 112,%esp'
prog.c:12:错误:没有这样的指令:`xorl%eax,%eax'
prog.c:13:错误:没有这样的指令:`popl%ebx'
程序:16:错误:没有这样的指令:`popl%esi'


这是代码:

#include <stdio.h>
#include <string.h>

int main(){
    char *x = "asbc4a2bab ";
    char *y = "ab";
    char bufor[100];
asm volatile (
    ".intel_syntax noprefix;"
    "mov ecx,%0;"
    "push ecx;" //wrzuca na stos
    "mov ecx,%1;"
    "mov eax,%2;"
    "call zadanie1;"
    "jmp wyjscie;"
    "zadanie1:"
    "push ebp;" //wrzucamy ebp na stos

    "push eax;"
    "push ecx;" //ecx zliczanie
    "push edi;" //edi destination
    "mov ebp,esp;" //do ebp adres stosu

    "mov esi,[ebp+20];" //esi bezposrednio do x
    "mov edi,[ebp+4];" //edi adres y
    "mov ebx,[ebp+8];"//ebx bufor
    "mov eax,0;"//eax to false
    "push eax;"
    "push esi;"
    "push eax;"
    "etykieta_x:"

    "mov eax,[esp+8];"
    "cmp eax,0;"
    "je etykieta_y;"
    "mov [esp+4],esi;"
    "mov eax,0;"
    "mov [esp+8],eax;"
    //"mov [esp+4],esi;"
        "etykieta_y:"

            "mov eax,[edi];"
            "cmp eax,'\0';" //porownoje eax z koncem
            "je koniec_etykiety_x;"
            "add edi,1;"//zwiekszamy petle
            "cmp eax,[esi];"//porownoje y i x
            "jne etykieta_y;"//wrocimy do etykiety y jesli nie sa rowne
            "ustaw_flage:"
                "pop eax;"
                "mov eax,1;" //ustawia flage
                "push eax;"

        "koniec_etykiety_x:"
        "pop eax;"
        "cmp eax,1;"
        "jne iteruj_dalej;"
        "mov eax,0;"
        "push eax;"

        "iteruj_po_znakach:"
            "add esi,1;"
            "mov eax,[esi];"
            "cmp eax,'\0';"
            "je koniec;"
            "cmp eax,' ';"
            "je spacja_wykryta;"
            "jmp etykieta_x;"

            "spacja_wykryta:"
                "mov eax,1;"
                "mov [esp+8],eax;"
                "jmp iteruj_po_znakach;"



        "iteruj_dalej:"
            "mov eax,0;"
            "push eax;"
            "add esi,1;"//zwiekszamy adres
            "mov eax,[esi];"//pobieramhy nast zznak
            "cmp eax,'\0';"
            "je zapisz_do_bufora;"
            "cmp eax,' ';"
            "je spacja_wykryta_2;"

                "mov eax,[esp+8];"
                "cmp eax,0;"
                "je etykieta_x;"
                "jmp zapisz_do_bufora;"

            "spacja_wykryta_2:"
            "mov eax,1;"
            "mov [esp+8],eax;"
            "jmp iteruj_dalej;"


            "zapisz_do_bufora:"
                "mov eax,[esp+4];"

                "interuj_po_slowie:"
                    "mov edx,[eax];"
                    "cmp edx,' ';"
                    "je etykieta_x;"
                    "cmp edx, '\0';"
                    "je etykieta_x;"

                    "mov [ebx],edx;"
                    "add eax,1;"
                    "add ebx,1;"
                    "jmp iteruj_po_slowie;"

    "koniec:"
    "pop edi;" //zdejmuje ze stosu
    "pop ecx;"
    "pop eax;"
    "pop ebp;"
    "ret;" //wyjdzie z funkcji
    "wyjscie:"
    ".att_syntax_prefix;"
    :
    :"r"(x), "r"(y), "r"(bufor)
    :"eax", "ecx"
    );
    return 0;
}


这是ideone链接:http://ideone.com/wHFeDK
有人知道怎么了吗?感谢帮助。

最佳答案

在嵌入式asm中手动切换语法模式是一个可怕的技巧,如果您有任何参数替换,它可能无法正常工作。正确的方法是使用-masm=intel(如果要使用intel语法)。

就是说,您的问题是您要恢复模式的指令中有一个错字:您有.att_syntax_prefix而不是.att_syntax prefix(注意,在prefix之前不需要其他下划线)。

另外,'\0'将不起作用,您应该只使用0

而且,您有一个错字:interuj_po_slowie vs iteruj_po_slowie

PS:Stackoverflow是一个英语论坛,请以英语发布代码,并对其进行正确注释。

08-16 20:09