【发布时间】:2020-11-14 14:00:32
【问题描述】:
我正在关注一个在线教程,该教程提供了用 NASM 语法编写的代码。 提供的代码是:
global _start
_start:
sub esp, 4
mov [esp], byte 'H'
mov [esp+1], byte 'e'
mov [esp+2], byte 'y'
mov [esp+3], byte '!'
mov eax, 4 ; sys_write system call
mov ebx, 1 ; stdout file descriptor
mov ecx, esp ; pointer to bytes to write
mov edx, 4 ; number of bytes to write
int 0x80 ; perform system call
mov eax, 1 ; sys_exit system call
mov ebx, 0 ; exit status is 0
int 0x80
我已尝试将其翻译成 AT&T 语法。我写了以下内容:
.global _start
_start:
sub $4, %esp
movb $'H', (%esp)
movb $'e', 1(%esp)
movb $'y', 2(%esp)
movb $'!', 3(%esp)
mov $4, %eax
mov $1, %ebx
mov %esp, %ecx
mov $4, %edx
int $0x80
mov $1, %eax
mov $0, %ebx
int $0x80
但是当我编译并执行这段代码时,我得到:
./build.sh: line 35: 1159 Segmentation fault (core dumped) ./$FILE
139
我从 NASM 到 AT&T 的翻译正确吗? 如果是这样,在能够从为堆栈分配的内存中读取/写入方面,我是否缺少一些东西? (权限等)
构建信息:
在 Arch Linux 上构建 64 位系统
build.sh 脚本:
function usage {
echo $'\nUsage: ./build.sh -f [filename]\n'
echo $' -f The filename of the source file to be compiled without the file extension.\n'
}
if [ $# -lt 1 ]; then
echo "No input files specified!"
usage
exit 1
fi
while [ $# -gt 0 ]; do
case "$1" in
-f)
shift
FILE=$1
shift
;;
*)
echo "Please use -f to specify the input file!"
usage
exit 1
;;
esac
done
if [ ! -f $FILE.s ]; then
echo "$FILE.s doesn't exist!"
usage
exit 1
fi
gcc -c $FILE.s -o $FILE.o
ld $FILE.o -o $FILE
./$FILE
echo $?
【问题讨论】:
-
你如何组装和执行你的代码?请出示您的
build.sh(无论如何,这应该是一个好的minimal reproducible example的一部分。 -
您是否将其构建为 64 位代码,因此您仅使用低半部分截断 RSP 中的 64 位堆栈指针?只有在您已经足够了解如何构建 + 运行以及任何可能的更深层次的问题以使其正确时,才能即时移植教程。但是,如果您知道正确的构建命令,只需更改语法就可以了,这与尝试将 32 位移植到 64 位或在 Mac 或 Windows 上使用 Linux 教程或其他东西不同。
-
无论如何,这要么是Assembling 32-bit binaries on a 64-bit system (GNU toolchain) 的副本,要么是没有构建命令不可见的其他东西,在这种情况下,由于缺少minimal reproducible example,应该关闭它。 (NASM 版本对你有用吗?如果没有,可能你在 Windows 上使用 WSL1,它不支持 32 位代码。)
-
我对你的问题投了反对票,因为它不包含minimal reproducible example,因此不承认准确的诊断。一旦您提供请求的构建脚本,将撤回我的反对票。
-
@fuz 我已经提供了请求的 build.sh 脚本,以及关于我正在构建的系统的一些更一般的信息
标签: assembly segmentation-fault stack nasm att