链接AC功能和ASM组装文件

发布于 2025-02-06 14:40:58 字数 2363 浏览 2 评论 0原文

我有一个后四个程序,该程序执行循环并打印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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜是你 2025-02-13 14:40:58

我不明白为什么,因为printf是在C中定义的,并在某处清楚地编码了

,因为您没有在某个地方链接(即,您没有与libc)链接。

在Unix系统上,您应该从不使用 使用ld链接所有内容(除了内核和启动加载程序外)。

相反,您应该始终 使用适当的编译器驱动程序(gcc在此处)。 GCC将自动将-LC添加到链接行。

ps您还应该定义main程序 - 目前尚不清楚如何调用代码,因为您定义了nighter main,nor _start象征。

如果我使用GCC -M32 -O P11 P11.O PRINT.O我获得以下错误:

默认情况下,您的gcc配置为构建pie二进制文件,但您的汇编为没有写成与馅饼兼容。

-fno-pie添加到您的编译行中,-no-pie flag flag到您的链接行。

I dont get why because printf is defined in c and clearly coded somewhere

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 nighter main, nor _start symbol.

if i use gcc -m32 -o p11 p11.o print.o i get the following error:

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文