链接AC功能和ASM组装文件
我有一个后四个程序,该程序执行循环并打印10个数字,并且需要一个我定义的外部打印函数,但是由于某些原因,如果我执行ld -m elf_i386 -s -s -o,则出于某种原因创建对象文件。 p11 p11.o print.o
它给了我一些奇怪的错误。
我想做的是链接这些文件并创建一个可执行的可执行文件,该文件将值从1到10打印出来,但是由于某种原因,当我想要的是我想要的是使用C函数打印这些值
PS:如果我使用<<, 则会给我这些错误。代码> gcc -m32 -o p11 p11.o print.o 我得到以下错误:
/usr/bin/ld: p11.o: warning: relocation in read-only section `.text'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib32/Scrt1.o: in function `_start':
(.text+0x22): undefined reference to `main'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
命令:
$ nasm -f elf32 p11.asm -o p11.o
$ gcc -m32 -o print.o -c print.c
$ ld -m elf_i386 -s -o p11 p11.o print.o
错误:
ld: warning: cannot find entry symbol _start; defaulting to 0000000008049000
ld: print.o: in function `print':
print.c:(.text+0x21): undefined reference to `printf'
我不明白为什么,因为printf是在c中定义的,并且在后缀程序中清楚地编码了
postfix程序:
EXTERN print ; extern print(int)
DATA
ALIGN
GLOBAL ix, OBJ; static ix
LABEL ix
SINT 0; static ix=0
TEXT
ALIGN
INT 0
DUP32
ADDR ix
STINT
TRASH 4
ALIGN
LABEL whilecond
ADDR ix
LDINT
INT 10
LT
JZ endwhile
ADDR ix
LDINT
INT 1
ADD
DUP32
ADDR ix
STINT
TRASH 4
ADDR ix
LDINT
CALL print
TRASH 4
JMP whilecond
ALIGN
LABEL endwhile
汇编程序:cprogram:
extern print
segment .data
align 4
global ix:object
ix:
dd 0
segment .text
align 4
push dword 0
push dword [esp]
push dword $ix
pop ecx
pop eax
mov [ecx], eax
add esp, 4
align 4
whilecond:
push dword $ix
pop eax
push dword [eax]
push dword 10
pop eax
xor ecx, ecx
cmp [esp], eax
setl cl
mov [esp], ecx
pop eax
cmp eax, byte 0
je near endwhile
push dword $ix
pop eax
push dword [eax]
push dword 1
pop eax
add dword [esp], eax
push dword [esp]
push dword $ix
pop ecx
pop eax
mov [ecx], eax
add esp, 4
push dword $ix
pop eax
push dword [eax]
call print
add esp, 4
jmp dword whilecond
align 4
endwhile:
c program :
#include <stdio.h>
void print(int num)
{
printf("%d\n",num);
}
I have a postfix program that does a while loop and prints 10 numbers, and it needs an extern print function which i defined, but for some reason after i create the object file if i do ld -m elf_i386 -s -o p11 p11.o print.o
it gives me some strange errors.
what i want to do is link those files and create an executable that prints values from 1 to 10, but for some reason its giving me those errors when clearly what i want is use that c function to print those values
ps: if i use gcc -m32 -o p11 p11.o print.o
i get the following error:
/usr/bin/ld: p11.o: warning: relocation in read-only section `.text'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib32/Scrt1.o: in function `_start':
(.text+0x22): undefined reference to `main'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
commands:
$ nasm -f elf32 p11.asm -o p11.o
$ gcc -m32 -o print.o -c print.c
$ ld -m elf_i386 -s -o p11 p11.o print.o
Error:
ld: warning: cannot find entry symbol _start; defaulting to 0000000008049000
ld: print.o: in function `print':
print.c:(.text+0x21): undefined reference to `printf'
I dont get why because printf is defined in c and clearly coded somewhere
postfix program:
EXTERN print ; extern print(int)
DATA
ALIGN
GLOBAL ix, OBJ; static ix
LABEL ix
SINT 0; static ix=0
TEXT
ALIGN
INT 0
DUP32
ADDR ix
STINT
TRASH 4
ALIGN
LABEL whilecond
ADDR ix
LDINT
INT 10
LT
JZ endwhile
ADDR ix
LDINT
INT 1
ADD
DUP32
ADDR ix
STINT
TRASH 4
ADDR ix
LDINT
CALL print
TRASH 4
JMP whilecond
ALIGN
LABEL endwhile
assembly program:
extern print
segment .data
align 4
global ix:object
ix:
dd 0
segment .text
align 4
push dword 0
push dword [esp]
push dword $ix
pop ecx
pop eax
mov [ecx], eax
add esp, 4
align 4
whilecond:
push dword $ix
pop eax
push dword [eax]
push dword 10
pop eax
xor ecx, ecx
cmp [esp], eax
setl cl
mov [esp], ecx
pop eax
cmp eax, byte 0
je near endwhile
push dword $ix
pop eax
push dword [eax]
push dword 1
pop eax
add dword [esp], eax
push dword [esp]
push dword $ix
pop ecx
pop eax
mov [ecx], eax
add esp, 4
push dword $ix
pop eax
push dword [eax]
call print
add esp, 4
jmp dword whilecond
align 4
endwhile:
c program:
#include <stdio.h>
void print(int num)
{
printf("%d\n",num);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
,因为您没有在某个地方链接(即,您没有与
libc
)链接。在Unix系统上,您应该从不使用 使用
ld
链接所有内容(除了内核和启动加载程序外)。相反,您应该始终 使用适当的编译器驱动程序(
gcc
在此处)。 GCC将自动将-LC
添加到链接行。ps您还应该定义
main
程序 - 目前尚不清楚如何调用代码,因为您定义了nightermain
,nor_start
象征。默认情况下,您的
gcc
配置为构建pie二进制文件,但您的汇编为没有写成与馅饼兼容。将
-fno-pie
添加到您的编译行中,-no-pie
flag flag到您的链接行。Because you are not linking that somewhere (namely, you are not linking with
libc
).On UNIX systems, you should never use
ld
to link anything (with the exceptions of the kernel and boot loader).Instead you should always use appropriate compiler driver (
gcc
here). Gcc will automatically add-lc
to the link line.P.S. you should also define the
main
program -- it's unclear how you expect your code to be invoked, since you defined nightermain
, nor_start
symbol.Your
gcc
is configured to build PIE binaries by default, but your assembly is not written to be compatible with PIE.Add the
-fno-pie
to your compile lines and-no-pie
flag to your link line.