IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 64位ubuntu20.04上编译32位汇编程序,并连接C库函数 -> 正文阅读

[C++知识库]64位ubuntu20.04上编译32位汇编程序,并连接C库函数

要解决的问题如下:

/usr/bin/ld: 当搜索用于 /usr/lib/x86_64-linux-gnu//libc.so 时跳过不兼容的 -lc

或者在连接的时候ld提示

ld: i386:x86-64 architecture of input file `multest.o’ is incompatible with i386 output

或者编译生成可执行文件运行后提示

bash: ./multest: 正在访问一个已毁坏的共享库。

我的系统是64位的ubuntu20.04。

汇编代码例子如下(已将入口点_start标签改为main)

# multest.s - An example of using the MUL instruction
.section .data
data1:
    .int 315814
data2:
    .int 165432
result:
    .quad 0
output:
    .asciz "The result is %qd\n"
.section .text
.globl main
main:
    nop
    movl data1, %eax
    mull data2
    movl %eax, result
    movl %edx, result+4
    pushl %edx
    pushl %eax
    pushl $output
    call printf
    add $12, %esp
    pushl $0
    call exit
    

方式一:gcc编译汇编语言程序

  • 使用gcc汇编程序时有一个问题,GNU连接器查找_start标签以便确定程序的开始位置,但是gcc查找的是main标签,所以必须把汇编程序中的_start标签改为main,如上面的程序示例所示。
  • 首先确保安装了libc6-dev-i386和lib32z1(ia32-libs已被lib32z1取代);
  • 然后就可以输入gcc命令成功编译连接成elf32可执行程序了:
gcc -m32 -o multest multest.s

在这里插入图片描述在这里插入图片描述

  • 把output中的格式字符串改为十六进制格式:
output:
     .asciz "The result is 0x%qx\n"   

在这里插入图片描述


方式二:as编译汇编语言程序

在这里插入图片描述
说是push操作无效,原因是 64 位系统和 32 位系统的差别引起的。

解决方法一

如果不修改源代码添加.code32指令的话,也不修改源代码为64位的汇编,要解决这个问题,就需要命令64位系统按照32位的去汇编,as参数是–32, ld参数是-m elf_i386,即:

as --32 -o multest.o multest.s

在这里插入图片描述我们可以看到,此时生存的.o目标文件是elf 32位的。
然后连接成可执行文件:

ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o multest -L /usr/lib32/ -lc multest.o

在这里插入图片描述

  • 这里重点要说明一下我的标准C库函数所在的位置:

-m elf_i386:表示按照elf_i386的模块进行连接,即32位的。
-dynamic-linker /lib/ld-linux.so.2:用于运行时动态加载libc.so动态库的。否则执行生成的可执行文件时会出错。
-lc: 因为程序中调用了标准的C库函数printf和exit,因此需要连接C动态库libc.so,所以需要参数-lc来指定连接的库文件,一般而言libxxx.so采用-lxxx的参数。
-L/lib:我的系统有多个libc.so,包括64位的,32位的,arm结构的,如下图所示,能搜出很多个libc.so。

在这里插入图片描述/usr/lib32/libc.so才是32位x86系统所需要的动态库,所以使用-L /usr/lib32来指定库文件的路径,那么-L /usr/lib32 –lc就指定了连接的是/usr/lib32/libc.so。

  • 他的libc.so都不兼容:
    在这里插入图片描述

尝试的解决方法二(未解决)

在代码开头添加 .code32 即可:
在这里插入图片描述

  • 当汇编语言程序被转换为可执行文件时,连接器必须知道指令码中的起始点是什么,GNU汇编器声明了一个默认标签_start作为应用程序的入口点,所以修改汇编程序中的main标签为_start标签:
    在这里插入图片描述

在这里插入图片描述我们可以看到,此时生存的.o目标文件是elf 64位的,这就会导致ld连接的时候出问题。

在这里插入图片描述

  • 因为.o目标文件是elf 64位的,所以我们链接的时候可以试试生存64位可执行文件的选项:
    在这里插入图片描述
    在这里插入图片描述 - 把加载动态库的程序,以及标准的C库函数也改为64位的试试:
    在这里插入图片描述仍然出错。。。只能待以后解决。。。

参考链接:
https://www.cnblogs.com/kenzhang1031/p/3411044.html
https://blog.csdn.net/q3733353520/article/details/38332465
https://blog.csdn.net/Asdfffy/article/details/88055350
http://cn.voidcc.com/question/p-yxssrsce-bgg.html
https://blog.csdn.net/weixin_39989159/article/details/116676721

GCC 64位程序的makefile条件编译心得——32位版与64位版、debug版与release版(兼容MinGW、TDM-GCC)
https://www.cnblogs.com/zyl910/archive/2012/08/14/gcc64_make.html

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-22 20:23:18  更:2022-02-22 20:24:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:34:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码