【发布时间】:2020-07-12 20:46:43
【问题描述】:
我有一个奇怪的问题
➜ ASM git:(master) ✗ ./Colleen
DEFAULT REL
SECTION .text
global _main
extern _printf
_main:
push rbx
lea rdi, [code]
mov rsi, 10
mov rdx, 34
lea rcx, [code]
xor rax, rax
call _printf
quit:
mov eax, 0x2000001
xor edi, edi
syscall ;end
code: "DEFAULT REL%1$cSECTION .text%1$cglobal _main%1$cextern _printf%1$c_main:%1$c push rbx%1$c lea rdi, [code]%1$c mov rsi, 10%1$c mov rdx, 34%1$c lea rcx, [code]%1$c xor rax, rax%1$c call _printf%1$cquit:%1$c mov eax, 0x2000001%1$c xor edi, edi%1$c syscall ;end%1$c%1$ccode: %2$c%3$s%2$c, 0%1$c", 0
➜ ASM git:(master) ✗ ./Colleen > a
➜ ASM git:(master) ✗ cat a
➜ ASM git:(master) ✗
似乎标准输出无法重定向到文件。 输出由一个简单的 printf 生成,任何其他方式生成的输出都可以正常工作,只是我的程序集有问题。 我在 Debian 上做了同样的事情,但我得到了同样的结果。
MacOS 源代码:
DEFAULT REL
SECTION .text
global _main
extern _printf
_main:
push rbx
lea rdi, [code]
mov rsi, 10
mov rdx, 34
lea rcx, [code]
xor rax, rax
call _printf
quit:
mov eax, 0x2000001
xor edi, edi
syscall ;end
code: db "DEFAULT REL%1$cSECTION .text%1$cglobal _main%1$cextern _printf%1$c_main:%1$c push rbx%1$c lea rdi, [code]%1$c mov rsi, 10%1$c mov rdx, 34%1$c lea rcx, [code]%1$c xor rax, rax%1$c call _printf%1$cquit:%1$c mov eax, 0x2000001%1$c xor edi, edi%1$c syscall ;end%1$c%1$ccode: %2$c%3$s%2$c, 0%1$c", 0
编译:
nasm -f macho64 Colleen.asm
clang -nostartfiles -arch x86_64 Colleen.o -o Colleen
Linux elf64 源代码
DEFAULT REL
SECTION .rodata
code: db "DEFAULT REL%1$cSECTION .rodata%1$ccode: db %2$c%3$s%2$c%1$c%1$cSECTION .text%1$cextern printf%1$cglobal _start%1$c_start:%1$c mov edi, code%1$c mov esi, 10%1$c mov edx, 34%1$c mov ecx, code%1$c xor eax, eax%1$c call printf%1$c%1$c mov eax, 60%1$c xor edi, edi%1$c syscall ;end%1$c"
SECTION .text
extern printf
global _start
_start:
mov edi, code
mov esi, 10
mov edx, 34
mov ecx, code
xor eax, eax
call printf
mov eax, 60
xor edi, edi
syscall ;end
编译:
nasm -f elf64 Colleen.asm
gcc -no-pie -nostartfiles Colleen.o -o Colleen
感谢您的帮助!
【问题讨论】:
-
请勿张贴文字或代码的图片。出于这个原因,我对你的问题投了反对票,一旦你用代码/文本替换你的图片,我就会收回反对票。
-
还有一般建议:您似乎在不使用 CRT 代码且不会通过
exit自行终止的二进制文件中使用 libc 函数。这可能会导致奇怪的问题。不要那样做。如果您使用 libc,请始终在 CRT 中链接(即不要使用-nostartfiles)并且不要执行原始存在系统调用。相反,请致电exit终止您的程序。 -
调用
exit函数。它在 libc 中。在 Linux 上:call exit。在 macOS 上:call _exit。阅读你的代码,我想你有通常的缓冲问题,因为你没有让 libc 有机会在退出时刷新它的缓冲区。 -
如果您以任何方式使用 libc,请考虑遵循我的其他建议并避免使用
-nostartfiles。 -
没有。我的意思是:使用提供
_start的CRT。此代码还为您初始化 libc。如果它没有在程序启动时运行,则某些 libc 函数可能无法工作。让您的汇编程序从main而不是_start开始,并像往常一样通过 C 编译器(但没有-nostartfiles)链接。