【问题标题】:how to use inline assembly(NASM) for file I/O如何使用内联汇编(NASM)进行文件 I/O
【发布时间】:2018-12-25 13:12:35
【问题描述】:

我尝试使用内联 NASM 在 stdout 中编写一个 char[](注意添加了 .intel_syntax 和 .att_syntax,以便可以使用 gcc 编译)

但它不会在标准输出中写入任何内容。

我在虚拟机上使用 Linux 16 (x86)

是 char c[] 的原因吗? (我通过这种编译方式读到我们不能使用内存变量,而是该怎么做?)

#include<stdio.h>


char c[] = "abcd";

int main(){
    asm (".intel_syntax noprefix");

    // write c into stdout
    asm("mov EAX,4"); // 4: write
    asm("mov EBX,1"); // 1: stdout
    asm("mov ECX,c");
    asm("mov EDX,5");
    asm("int 0x80");

    // exit program
    asm("mov EAX,1")
    asm("int 0x80")

    asm (".att_syntax noprefix");
}

输出什么都没有

【问题讨论】:

    标签: c assembly inline-assembly


    【解决方案1】:

    GNU 汇编器(这是 gcc 使用的)不使用 NASM 语法。它宁可使用 Microsoft 的 MASM 语法的变体,其中不需要括号来取消引用变量。由于您不想加载 c 变量的值而是其地址,因此您需要一个 offset 关键字:

    mov ecx, offset c
    

    我强烈建议您在学习汇编时尽量避免使用内联汇编。在 gcc 中使用内联汇编需要很好地了解整个事情是如何工作的,并且编写随机指令通常会导致错误的代码。即使是您的简单代码也已经从根本上被破坏了,如果它比这更复杂,也将无法工作(因此编译器有机会尝试使用您在不告知的情况下覆盖的寄存器)。

    相反,请将您的程序集放在一个单独的文件中并将其链接到其中。这可以回避您在使用内联程序集时遇到的所有问题,并允许您根据需要使用 NASM。例如,尝试这样的操作:

    main.c

    char c[] = "abcd";
    
    /* the function you define in print_c.asm */
    extern void print_c();
    
    int main() {
        print_c(); /* call your assembly function */
    }
    

    print_c.asm

        ; pull in c defined in main.c
        extern c
    
        section .text
    
        global print_c
    
    print_c:
        ; write c to stdout
        mov eax, 4
        mov ebx, 1
        mov ecx, c
        mov edx, 5
        int 0x80
    
        ; exit program
        mov eax, 1
        int 0x80
    

    然后组装、编译和链接:

    nasm -felf print_c.asm
    cc -m32 -o print_c print_c.o main.c
    

    【讨论】:

    • 谢谢 :) 我想将它与 QT 文件链接以用于 GUI 目的,我搜索了是否有办法在没有内联汇编的情况下执行此操作,似乎至少对于 x86 汇编没有建议例如,我尝试按照您所说的那样制作单独的 .asm 文件,然后从 C 调用它们,但 QT 无法链接 .asm 并且没有引用 ... 函数
    • 这是我试图链接它们但没有用的:stackoverflow.com/questions/44943948/…
    • @Me.a 您需要将所有函数标记为global,以便链接器看到它们。然后它应该可以工作。在您链接的代码中,适用于 Windows 的 OP 程序,其中外部函数需要在程序集中使用下划线作为前缀。这就是为什么他的代码没有链接。当您为 Linux 编程时,您不会受此影响。如果您需要进一步的帮助,请发布您的代码,我可以为您提供帮助。
    • 哦,当然,我会处理它,如果我有任何其他问题,我会在这里发布。谢谢:)
    猜你喜欢
    • 2011-01-07
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 2012-05-26
    相关资源
    最近更新 更多