다음 NASM 명령을 사용하여 다음 어셈블리 소스 파일을 어셈블하려고 합니다.
nasm -f elf -o test.o test.asm
오류 없이 완료되면 실행 파일을 다음 위치에 연결하려고 합니다 ld
.
ld -m elf_i386 -e main -o test test.o -lc
이것도 성공한 것 같았고 실행 파일을 실행해 보았습니다.
$ ./test
bash: ./test: No such file or directory
불행히도 작동하지 않는 것 같습니다. ldd
실행 파일에서 실행을 시도했습니다 .
linux-gate.so.1 => (0xf777f000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7598000)
/usr/lib/libc.so.1 => /lib/ld-linux.so.2 (0xf7780000)
패키지를 설치 lsb-core
하고 /lib/ld-linux.so.2
존재하는지 확인했습니다. 여전히 실행 파일을 실행할 수 없는 이유는 무엇입니까?
저는 64비트 버전의 Ubuntu 15.04를 실행하는 컴퓨터에서 이 작업을 시도했습니다.
소스 코드:
; This code has been generated by the 7Basic
; compiler <http://launchpad.net/7basic>
extern printf
extern scanf
extern read
extern strlen
extern strcat
extern strcpy
extern strcmp
extern malloc
extern free
; Initialized data
SECTION .data
s_0 db "Hello, World!",0
printf_i: db "%d",10,0
printf_s: db "%s",10,0
printf_f: db "%f",10,0
scanf_i: db "%d",0
scanf_f: db "%lf",0
; Uninitialized data
SECTION .bss
v_12 resb 4
v_0 resb 4
v_4 resb 8
SECTION .text
; Code
global main
main:
finit
push ebp
mov ebp,esp
push 0
pop eax
mov [v_12], eax
l_0:
mov eax, [v_12]
push eax
push 5
pop edx
pop eax
cmp eax, edx
jl l_2
push 0
jmp l_3
l_2:
push 1
l_3:
pop eax
cmp eax, 0
je l_1
push s_0
push printf_s
call printf
add esp, 8
mov eax, [v_12]
push eax
push 1
pop edx
pop eax
add eax, edx
push eax
pop eax
mov [v_12], eax
jmp l_0
l_1:
mov esp,ebp
pop ebp
mov eax,0
ret
출력은 다음과 같습니다 strings test
.
/usr/lib/libc.so.1
libc.so.6
strcpy
printf
strlen
read
malloc
strcat
scanf
strcmp
free
GLIBC_2.0
t'hx
Hello, World!
.symtab
.strtab
.shstrtab
.interp
.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rel.plt
.text
.eh_frame
.dynamic
.got.plt
.data
.bss
test.7b.out
printf_i
printf_s
printf_f
scanf_i
scanf_f
v_12
_DYNAMIC
_GLOBAL_OFFSET_TABLE_
strcmp@@GLIBC_2.0
read@@GLIBC_2.0
printf@@GLIBC_2.0
free@@GLIBC_2.0
_edata
strcat@@GLIBC_2.0
strcpy@@GLIBC_2.0
malloc@@GLIBC_2.0
scanf@@GLIBC_2.0
strlen@@GLIBC_2.0
_end
__bss_start
main
답변1
crt1.o
libc 함수를 호출하려면 시작 프래그먼트(예: 다른 프래그먼트)도 연결해야 합니다. 연결 프로세스는 상당히 복잡할 수 있으므로 이를 사용하는 것이 좋습니다 gcc
.
amd64 Ubuntu에서는 다음을 수행할 수 있습니다.
sudo apt-get install gcc-multilib
gcc -m32 -o test test.o
옵션을 추가하면 연결된 파일과 명령을 볼 수 있습니다 -v
.