как использовать встроенную сборку (NASM) для файлового ввода-вывода - PullRequest
0 голосов
/ 25 декабря 2018

Я пытался написать char [] в stdout, используя встроенный NASM (обратите внимание: добавлены .intel_syntax и .att_syntax, чтобы его можно было скомпилировать с помощью gcc)

, но он ничего не пишет в stdout.

Я использую 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");
}

вывод ничто

1 Ответ

0 голосов
/ 25 декабря 2018

Ассемблер GNU (который использует gcc) не использует синтаксис NASM.Он скорее использует вариант синтаксиса MASM от Microsoft, где для разыменования переменной не нужны скобки.Поскольку вы не хотите загружать значение переменной 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
...