大会,没有这样的指令popl?

时间:2014-12-02 00:51:38

标签: c gcc assembly x86 inline-assembly

我在C中有一个代码,其中主要是用汇编语言编写的。程序的想法是例如当x = abc def,并且y = a时,它删除至少一个字母相同的单词并且写出没有相同字母的单词,因此它将写入def。我编写了一个代码,但它给出了错误:

  • prog.c:10:错误:没有这样的指示:`addl $ 112,%esp'
  • prog.c:12:错误:没有这样的指示:`xorl%eax,%eax'
  • prog.c:13:错误:没有这样的指示:`popl%ebx'
  • prog.c: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 有人知道可能有什么问题吗?谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

在内联asm中手动切换语法模式是一个可怕的黑客,如果你有任何参数替换它可能不起作用。如果你想要英特尔语法,正确的方法是使用-masm=intel

那就是说,你的问题是你在指令中有一个拼写错误你要恢复模式:你有.att_syntax_prefix而不是.att_syntax prefix(注意你之前不需要另一个下划线{ {1}})。

此外,prefix无法使用,您只需使用'\0'

而且,您有一个拼写错误:0 vs interuj_po_slowie

PS:Stackoverflow是一个英语论坛,请用英语发布代码,并正确评论。