如何对文件 I/O 使用内联汇编 (NASM)
how to use inline assembly(NASM) for file I/O
我尝试使用内联 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");
}
输出什么都没有
GNU assembler(gcc 使用的)不使用 NASM 语法。它而是使用 Microsoft 的 MASM 语法的变体,其中不需要括号来取消引用变量。由于您不想加载 c
变量的值而是它的地址,因此您需要一个 offset
关键字:
mov ecx, offset c
我强烈建议您在学习汇编时尽可能避免使用内联汇编。在 gcc 中使用内联汇编需要很好地了解整个事情的具体工作原理,并且编写随机指令通常会导致错误代码。即使你的简单代码已经从根本上被破坏了,如果它比这更复杂就无法工作(所以编译器有机会尝试使用你覆盖的寄存器而不告诉)。
相反,将您的程序集放在一个单独的文件中,然后 link 将其放入。这会回避您使用内联汇编时遇到的所有问题,并允许您根据需要使用 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
然后 assemble,编译,然后 link 使用:
nasm -felf print_c.asm
cc -m32 -o print_c print_c.o main.c
我尝试使用内联 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");
}
输出什么都没有
GNU assembler(gcc 使用的)不使用 NASM 语法。它而是使用 Microsoft 的 MASM 语法的变体,其中不需要括号来取消引用变量。由于您不想加载 c
变量的值而是它的地址,因此您需要一个 offset
关键字:
mov ecx, offset c
我强烈建议您在学习汇编时尽可能避免使用内联汇编。在 gcc 中使用内联汇编需要很好地了解整个事情的具体工作原理,并且编写随机指令通常会导致错误代码。即使你的简单代码已经从根本上被破坏了,如果它比这更复杂就无法工作(所以编译器有机会尝试使用你覆盖的寄存器而不告诉)。
相反,将您的程序集放在一个单独的文件中,然后 link 将其放入。这会回避您使用内联汇编时遇到的所有问题,并允许您根据需要使用 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
然后 assemble,编译,然后 link 使用:
nasm -felf print_c.asm
cc -m32 -o print_c print_c.o main.c