"No such file or directory" 尝试执行二进制文件时出错

"No such file or directory" error when trying to execute a binary

我在 Ubuntu 上使用 NASM 汇编程序。我正在尝试执行此代码:

section .data

fmt db "%d",0
val1 dd 23
val2 dd 9
val3 dd 7

section .text
global _start
extern printf

_start:
push val1
push val2
push val3

pop rax 
pop rbx 
imul rax, rbx
push rax 

pop rax 
pop rbx 
add rax, rbx
push rax

pop rax 
mov [val1], rax

push val1
push fmt
call printf
add rsp, 16

mov rax,0   
ret 

nasm -f elf64 test64.asm 成功创建了 test64.o 并且 ld -s -o hello test64.o -lc 创建了一个可执行文件,但是当我尝试 运行 它时,我得到一个 "No such file or directory" 错误。

  1. 您是否尝试过启动它?

    ./test
    

可能是,当前路径不在路径列表中,在哪里搜索可执行文件。

  1. 检查权限是否允许执行文件,例如:

    $ ls ./test
    
    -rwxr-xr-x user user .... test
    

1) 您对 printf 使用了错误的调用约定。参数在寄存器中传递,而不是在堆栈中传递:https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI。此外,printf 需要 EAX 中的值(在您的情况下为 0)。

2)程序启动时,栈上没有return地址。看这里:http://www.dreamincode.net/forums/topic/285550-nasm-linux-getting-command-line-parameters。因此,

mov rax,0   
ret 

错了。但是如果你使用 64-bit-Linux-syscall

mov edi, 0                  ; return 0 (success)
mov eax, 60                 ; sys_exit
syscall

您不会看到 printf 的输出,因为它已被缓冲并且不会刷新缓冲区。您可以调用 fflush(0)exit.

3) 要在 Linux 中使用 C 函数,您必须 link 使用特殊的加载器 (/lib64/ld-linux-x86-64.so.2)。就是不知道有没有默认安装

4) push val1 压入 val1 的 地址 ,而不是它的值。使用括号获取值。我猜你只想将 32 位 DWORD 加载到 64 位寄存器中。可以直接将DWORD加载到32位寄存器中(64位寄存器的高位会被清零)或者使用movsx进行有符号运算。

精粹:

section .data

fmt db `%d\n`,0             ; backticks for '\n'
val1 dd 23
val2 dd 9
val3 dd 7

section .text
global _start
extern printf, exit

_start:

movsx rax, dword [val1]     ; signed dword to signed qword
movsx rbx, dword [val2]
imul rax, rbx

mov ebx, [val3]             ; unsigned dword into RBX
add rax, rbx
mov [val1], rax

mov rdi, fmt                ; string pointer
mov rsi, [val1]             ; immediate value
xor eax, eax                ; no vector registers used
call printf

xor edi, edi
call exit

nasm -f elf64 test64.asm
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test64 test64.o -lc
./test64