我开始学习汇编,我选择的编译器是 GNU AS。唯一可怕的是几乎没有关于 AS 的文档,它的语法和用户指南。
我编写了一个 hello world 程序,它读取一个文本文件(文件路径是程序的第一个参数)并将其内容显示到标准输出。但是当我运行程序时,它总是说“段错误”。在稍微修改源代码后,我发现我在读取程序的输入参数时遇到了问题。如果我将文件路径放在源代码中,没有问题,但如果我从输入参数中读取它,则会发生“分段错误”。
这是我关于读取输入参数的源代码
# get file name from argument and put in to ebx
movl 8(%esp), %ebx
# open the file
# movl $path, %ebx
movl $5, %eax
movl $0, %ecx
movl $0666, %edx
int $0x80
我已经搜索了很多关于在 GAS 中读取输入参数的信息,但我只找到了这篇非常好的文章:NASM - Linux Getting command line parameters。我复制了代码并将其更改为 x64(我的机器是 kali x64)。有趣的是,我再次遇到了“分段错误”。多么悲伤的一天!!!
因此,如果有人在 Linux 中使用过 assemby,尤其是使用 GAS 或 NASM,请帮我解决这个问题。
1000+ 感谢(如果可能的话)您的帮助
聪。
update1:这是我的完整源代码
.global main
.text
main:
# get file name from parameter and put in to ebx
movl 8(%esp), %ebx
# read path in source code
# movl $path, %ebx
# open the file
# movl $path, %ebx
movl $5, %eax
movl $0, %ecx
movl $0666, %edx
int $0x80
# read the file
movl %eax, %ebx
movl $3, %eax
movl $buf, %ecx
movl $bufSize, %edx
int $0x80
# write to stdout
movl %ebx, %ebp
movl $4, %eax
movl $1, %ebx
movl $buf, %ecx
int $0x80
# close the file
movl $6, %eax
movl %ebp, %ebx
int $0x80
exit:
movl $1, %eax
movl $0, %ebx
int $0x80
.data
path:
.asciz "./hello_world.c"
.bss
.equ bufSize, 1024
.lcomm buf, bufSize
更新 2:我的操作系统是 x86_64,这是我在 x86_64 中编写程序集时遇到的许多问题的根源。在@user35443 和@Jester 的帮助下,我终于可以找到一些解决方法:编译为x86 elf 文件,而不是x64 elf。源代码与上面相同,只是将main更改为_start。而且因为我在x86_64上编译x86,所以我需要一些东西:apt-get install gcc-multilib
之后,编译就很简单了:as --32 readfile.s -o readfile.o && ld -m elf_i386 readfile.o -o readfile && ./readfile some_text_file
(ps:我不知道为什么gcc -m32 readfile.s
会出现错误)
.global _start
.text
_start:
# get file name from parameter and put in to ebx
movl 8(%esp), %ebx
# movl $path, %ebx
# open the file
# movl $path, %ebx
movl $5, %eax
movl $0, %ecx
movl $0666, %edx
int $0x80
# read the file
movl %eax, %ebx
movl $3, %eax
movl $buf, %ecx
movl $bufSize, %edx
int $0x80
# write to stdout
movl %ebx, %ebp
movl $4, %eax
movl $1, %ebx
movl $buf, %ecx
# size of write is %edx
int $0x80
# close the file
movl $6, %eax
movl %ebp, %ebx
int $0x80
exit:
movl $1, %eax
movl $0, %ebx
int $0x80
.data
path:
.asciz "./hello_world.c"
.bss
.equ bufSize, 1024
.lcomm buf, bufSize
因为我专注于x86_64,所以我会让问题开放几天,这是我找不到问题根源的x84_64源代码(可能我误用了x86_64调用约定)。
.global main
.text
main:
# get file name from parameter and put in to rbx
movq 16(%rsp), %rbx
#movq $path, %rbx
# open the file
# movq $path, %rbx
movq $5, %rax
movq $0, %rcx
movq $0666, %rdx
int $0x80
# read the file
movq %rax, %rbx
movq $3, %rax
movq $buf, %rcx
movq $bufSize, %rdx
int $0x80
# write to stdout
movq %rbx, %rbp
movq $4, %rax
movq $1, %rbx
movq $buf, %rcx
# size of write is %rdx
int $0x80
# close the file
movq $6, %rax
movq %rbp, %rbx
int $0x80
exit:
movq $1, %rax
movq $0, %rbx
int $0x80
.data
path:
.asciz "./hello_world.c"
.bss
.equ bufSize, 1024
.lcomm buf, bufSize