汇编语言程序设计读书笔记(2)- 相关工具64位系统篇
2013-11-06 18:03
253 查看
汇编语言程序设计一书,在32位系统下应该不会有什么问题,然而在64位系统下,则会有些不一样的地方。有些程序范例还会汇编错误或者执行错误。
博主所用系统为CentOS v6.4 x64。本文主要解决32位的汇编程序如何在64位环境下汇编、连接,而不论述64位汇编语言如何设计。
这个代码的具体实现,后续的章节会介绍。目前只知道是用于输出CPU厂商ID字符串的就行了。
在64位系统下,如果按照书中所述的那样as和ld,会产生错误,如下图:
说是push操作无效。
如果不修改源代码为64位的汇编,要解决这个问题,就需要命令64位系统按照32位的去汇编,as参数是--32, ld参数是-m elf_i386。如下图:
file cpuid2可以看到确实是32位的文件,而且执行也没有问题。这里要特别对ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o cpuid2 -L/lib -lc cpuid2.o这行命令进行说明。
-m elf_i386:表示按照elf_i386的模块进行连接,即32位的。
-lc: 因为程序中调用了标准的C库函数printf和exit,因此需要连接C动态库libc.so,所以需要参数-lc来指定连接的库文件,一般而言libxxx.so采用-lxxx的参数。
-L/lib:博主的系统有多个libc.so,包括64位的,32位的,arm结构的,如下图所示,能搜出很多个libc.so。
而/lib/libc.so才是32位x86系统所需要的动态库,所以使用-L/lib来指定库文件的路径,那么-L/lib –lc就指定了连接的是/lib/libc.so。
-dynamic-linker /lib/ld-linux.so.2:用于运行时动态加载libc.so动态库的。否则执行生成的可执行文件时会出错。
对gcc -nostdlib -m32 -o cpuid2 cpuid2.s -L/lib -lc进行说明。
-m32:按照32位的编译。
-nostdlib:如果没有这个参数,gcc会连接gnu库的函数,该函数会以_start为进入点,执行一段程序后,跳到main执行,而这个汇编源程序中用_start做进入点,而且没有main,因此,没有这个参数的话,会提示没有main定义以及重复定义_start的错误。加了这个参数后,则不会去连接gnu函数。
综上所述,64位系统下汇编32位汇编程序的做法是:
as --32 –o output_file.o input_file.s
ld –m elf_i386 –dynamic-linker /lib/ld-linux.so.2 –o output_file –L/path –llibname input_file.s
或者
gcc –m32 –nostdlib –o output_file –L/path –llibname input_file.s
博主所用系统为CentOS v6.4 x64。本文主要解决32位的汇编程序如何在64位环境下汇编、连接,而不论述64位汇编语言如何设计。
1. 64位系统下编译32位的C程序
以程序test5.c为例,程序代码很简单,如下:cpuid2.s# cpuid2.s file .section .data output: .asciz "CPUID is '%s'\n" .section .bss .lcomm buffer, 12 .section .text .globl _start _start: nop movl $0, %eax cpuid movl $buffer, %edi movl %ebx, (%edi) movl %edx, 4(%edi) movl %ecx, 8(%edi) pushl $buffer pushl $output call printf addl $8, %esp pushl $0 call exit
这个代码的具体实现,后续的章节会介绍。目前只知道是用于输出CPU厂商ID字符串的就行了。
在64位系统下,如果按照书中所述的那样as和ld,会产生错误,如下图:
说是push操作无效。
如果不修改源代码为64位的汇编,要解决这个问题,就需要命令64位系统按照32位的去汇编,as参数是--32, ld参数是-m elf_i386。如下图:
file cpuid2可以看到确实是32位的文件,而且执行也没有问题。这里要特别对ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o cpuid2 -L/lib -lc cpuid2.o这行命令进行说明。
-m elf_i386:表示按照elf_i386的模块进行连接,即32位的。
-lc: 因为程序中调用了标准的C库函数printf和exit,因此需要连接C动态库libc.so,所以需要参数-lc来指定连接的库文件,一般而言libxxx.so采用-lxxx的参数。
-L/lib:博主的系统有多个libc.so,包括64位的,32位的,arm结构的,如下图所示,能搜出很多个libc.so。
而/lib/libc.so才是32位x86系统所需要的动态库,所以使用-L/lib来指定库文件的路径,那么-L/lib –lc就指定了连接的是/lib/libc.so。
-dynamic-linker /lib/ld-linux.so.2:用于运行时动态加载libc.so动态库的。否则执行生成的可执行文件时会出错。
3). 64位系统下用gcc汇编32位的汇编程序
还是以上面的cpuid2.s为例,使用gcc -m32的参数进行汇编成32位的系统文件,特别的,这里由于没有main函数,而是用_start做入口点,因此需要使用参数 –nostdlib,如下图:对gcc -nostdlib -m32 -o cpuid2 cpuid2.s -L/lib -lc进行说明。
-m32:按照32位的编译。
-nostdlib:如果没有这个参数,gcc会连接gnu库的函数,该函数会以_start为进入点,执行一段程序后,跳到main执行,而这个汇编源程序中用_start做进入点,而且没有main,因此,没有这个参数的话,会提示没有main定义以及重复定义_start的错误。加了这个参数后,则不会去连接gnu函数。
综上所述,64位系统下汇编32位汇编程序的做法是:
as --32 –o output_file.o input_file.s
ld –m elf_i386 –dynamic-linker /lib/ld-linux.so.2 –o output_file –L/path –llibname input_file.s
或者
gcc –m32 –nostdlib –o output_file –L/path –llibname input_file.s
相关文章推荐
- 汇编语言程序设计读书笔记(2)- 相关工具64位系统篇
- Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- 测试相关工具和其他系统UserName和PassWord,不难记
- 『系统开发』几款BI相关的开源工具
- Linux系统调优相关工具
- Linux 查看磁盘分区、文件系统、磁盘的使用情况相关的命令和工具介绍
- 系统相关功能开发(五)-系统工具
- 64位系统兼容32位工具
- 在64位的CentOS 6.8上安装系统性能监测工具Monitorix
- 系统性能相关工具列表
- Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- ubuntu64位系统用32位的交叉工具链
- 做个调查:大家开发与数据库相关的系统都使用什么数据库工具
- Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- 文件系统管理 之 Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- ubuntu64位系统用32位的交叉工具链
- LINUX下使用elasticsearch-jdbc工具实现MySQL同步到ElasticSearch 以及linux 64位centos系统安装jdk1.8