【问题标题】:Assembly , no such instruction popl?汇编,没有这样的指令popl?
【发布时间】:2014-12-02 00:51:38
【问题描述】:

我有一个 C 代码,其中 main tak 是用汇编编写的。该程序的想法是,例如,当 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 有人知道可能出了什么问题吗?感谢您的帮助。

【问题讨论】:

  • 适用于什么平台和编译器?
  • 您意识到已经有一个几乎相同的问题悬而未决?
  • 应该为 linux , nasm 做

标签: c gcc assembly x86 inline-assembly


【解决方案1】:

在 inline asm 中手动切换语法模式是一种可怕的 hack,如果您有任何参数替换,它可能无法正常工作。如果需要 intel 语法,正确的方法是使用-masm=intel

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

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

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

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

【讨论】:

    猜你喜欢
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    相关资源
    最近更新 更多