要解决的问题如下:
或者在连接的时候ld提示
或者编译生成可执行文件运行后提示
我的系统是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库函数所在的位置:
而
/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