c - Assembly ,没有这样的指令 popl 吗?

标签 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 有人知道可能出了什么问题吗?感谢您的帮助。

最佳答案

在内联汇编中手动切换语法模式是一个可怕的黑客行为,如果您有任何参数替换,它可能不起作用。如果您需要 intel 语法,正确的方法是使用 -masm=intel

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

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

而且,您有一个拼写错误:interuj_po_slowieiteruj_po_slowie

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

关于c - Assembly ,没有这样的指令 popl 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27240085/

相关文章:

c - 客户端完成消息传递后,服务器无法退出接受循环

c++ - 传递 GCcflags -std=c++11 CXXFLAGS 或 CXX 或 CFLAGS

c - 如何找出分配一个字符数组的空间大小

c - 编译后与c文件相同的可执行文件名称

c++ - nullptr 可以转换为 uintptr_t 吗?不同的编译器不同意

assembly - 为什么我不能保存 rip 的值?

c - 使用预处理器输出作为内联汇编

assembly - 什么是更快的 : JMP or string of NOPs?

c - 在 Gtk 中重绘小部件

c - GCC pragma 优化不覆盖 `-Og` 命令行设置