Me.a
Me.a

Reputation: 109

how to use inline assembly(NASM) for file I/O

I tried to write a char[] in stdout using inline NASM (note .intel_syntax and .att_syntax are added so it can be compiled with gcc)

but it doesn't write anything in stdout.

I am using Linux 16 (x86) on Virtual machine

Is it cause of char c[] ? ( I read by this way of compiling we cannot use memory variables but what to do instead?)

#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");
}

the output is nothing

Upvotes: 0

Views: 878

Answers (1)

fuz
fuz

Reputation: 92986

The GNU assembler (which is what gcc uses) does not use NASM syntax. It rather uses a variant of Microsoft's MASM syntax where no brackets are needed to dereference a variable. Since you don't want to load the value of the c variable but rather its address, you need an offset keyword:

mov ecx, offset c

I strongly recommend you to avoid inline assembly as much as possible for learning assembly. Using inline assembly in gcc requires good knowledge of how exactly this whole thing works and writing random instructions usually leads to wrong code. Even your simple code is already fundamentally broken and would not work if it was any more complicated than that (so the compiler had a chance to try to use the registers you overwrote without telling).

Instead, put your assembly in a separate file and link it in. This sidesteps all issues you have with inline assembly and allows you to use NASM as you wanted. For example, try something like this:

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

Then assemble, compile, and link with:

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

Upvotes: 4

Related Questions