由于使用as和ld来编译链接汇编程序,在使用C库的时候比较麻烦,需要输入比较多的指令,所以使用gcc进行编译链接。由于书中内容是32位汇编程序,但是机器使用的是64位操作系统,自带的gcc也是64位的,导致编译生成的程序,一运行就会Segment Fault。经过查询之后,发现是调用printf函数的时候,总是报错,查询之后发现是32位汇编和64位汇编在调用C库的时候,32位使用pushl指令来压栈传递参数,而64位汇编是使用通用寄存器来传递参数的。

  32汇编的代码是:

 .code32
.section .data
output:
.asciz "The processor Vendor ID is '%s'\n" .section .bss
.lcomm buffer, .section .text
.globl main
main:
movl $, %eax
cpuid movl $buffer, %edi
movl %ebx, (%edi)
movl %edx, (%edi)
movl %ecx, (%edi) pushl $buffer
pushl $output
call printf
addl $, %esp pushl $
call exit

  64位汇编需要这么写:

.section .data
output:
.asciz "The Processor Vendor ID is '%s'\n"
.section .bss
.lcomm buffer,
.section .text
.globl main
main:
movq $, %rax
cpuid
movq $buffer, %rdi
movq %rbx, (%rdi)
movq %rdx, (%rdi)
movq %rcx, (%rdi)
movq $buffer, %rsi #1st parameter
movq $output, %rdi #2nd parameter
movq $, %rax
call printf
addq $, %rsp
pushq $
call exit

  从两种代码中可以看出来,64位汇编首先mov使用的是movq,32位是movl,而且64位调用printf使用的通用寄存器传递参数,而32位使用的是pushl压栈来传递参数的。

  但是64位gcc编译生成的32位汇编程序运行就会报错,所以需要让gcc兼容32位汇编,首先在编译的时候加上-m32参数选项,但是光这样,编译的时候会报错,还需要下载gcc的32位兼容包,在ubuntu下使用的指令

  sudo apt-get install g++-multilib libc6-dev-i386,参考http://www.cyberciti.biz/tips/compile-32bit-application-using-gcc-64-bit-linux.html

  然后再使用指令gcc -g -m32 -o cpuid2 cpuid2.s编译生成,就可以正常运行了

64位gcc编译32位汇编的更多相关文章

  1. 64位linux编译32位程序

    昨天接到的任务,编译64位和32位两个版本的.so动态库给其他部门,我的ubuntu虚拟机是64位的,编译32位时遇到了问题: /usr/bin/ld: cannot find -lstdc++ 最后 ...

  2. 64位ubuntu编译32位程序

      最近在64位ubuntu上开发,需要编译32位程序,需要安装这两个包,然后在编译器参数加上-m32.不放心的话可以用ldd或file查看一下是否生成了对应位数的程序. $ apt-get inst ...

  3. MacOSX64位机器上gcc编译32位x264静态库

    x264最新包地址:http://www.videolan.org/developers/x264.html 编译命令: ./configure --enable-static --host=i386 ...

  4. <摘录>如何在64位linux强制编译32位应用程序

    GDC注:因为需要解决在linux64机上编译32位的mongodb(没办法,因为编译的php是32位,然后我想将mongdb扩展添加到php中),在网上搜了很多文章,感觉这篇好懂,而且好用.我使用的 ...

  5. hadoop2.6.0汇总:新增功能最新编译 32位、64位安装、源码包、API下载及部署文档

    相关内容: hadoop2.5.2汇总:新增功能最新编译 32位.64位安装.源码包.API.eclipse插件下载Hadoop2.5 Eclipse插件制作.连接集群视频.及hadoop-eclip ...

  6. hadoop2.5发布:最新编译 32位、64位安装、源码包、API以及新特性

    hadoop2.5发布:最新编译 32位.64位安装.源码包.API以及新特性 http://www.aboutyun.com/thread-8751-1-1.html (出处: about云开发) ...

  7. 【原创】在Windows系统中使用VC9、VC11编译32位、64位PHP及其扩展

    项目中需要使用runkit模块实现AOP,但是团队成员的开发环境都是Windows,而runkit模块官方没有提供Windows环境下的dll扩展,只能自己编译. 下面是编译过程的分类总结.(操作系统 ...

  8. 在64位Ubuntu上编译32位程序常见错误

    问       题1: 找不到头文件 asm/errno.h 解决办法 : [/usr/lib/gcc$ ]sudo ln -s x86_64-linux-gnu/asm asm 问题2:找不到gcc ...

  9. 在64位linux下编译32位程序

    在64位linux下编译32位程序 http://blog.csdn.net/xsckernel/article/details/38045783

随机推荐

  1. 转python编码问题

    python的编码问题 http://blog.csdn.net/fuadam/article/details/5547504 分类: .net以外的东东 2010-04-30 21:16 747人阅 ...

  2. webapi方式

    随笔 - 112  文章 - 0  评论 - 334 ASP.NET MVC学习系列(二)-WebAPI请求   继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前 ...

  3. CentOS Hadoop格式化HDFS异常java.net.UnknownHostException

    #bin/hadoop namenode -format DEPRECATED: Use of this script to execute hdfs command is deprecated. I ...

  4. js里面引入js

    document.write('<script src="http://js.xcar.com.cn/bbs/sidebar/js/publicSidebar.js"> ...

  5. bzoj 2244: [SDOI2011]拦截导弹

    #include<cstdio> #include<iostream> #include<algorithm> #define M 100009 using nam ...

  6. C-指针与引用的区别

    1. 指针是一个变量,保存一个地址,指向内存中的一个单元.而引用是一个别名. int a = 1; int* p = &a; int b = 1; int& r = b; 2. 指针可 ...

  7. io函数

    io函数一般分为两大类: 系统(不带缓存)调用: 如read.write.open 标准(带缓存)调用: fread.fwrite.fopen 上面说的带缓存/不带缓存是针对用户态的,内核态本身都是带 ...

  8. C++中两块内存重叠的string的copy方法

    如果两段内存重叠,用memcpy函数可能会导致行为未定义. 而memmove函数能够避免这种问题,下面是一种实现方式: #include <iostream> using namespac ...

  9. xcode开发的6个小技巧

    Xcode是iPhone和iPad开发者用来编码或者开发iOS app的IDE.Xcode有很多小巧但很有用的功能,很多时候我们可能没有注意到它们,也或者我们没有在合适的水平使用这些功能简化我们的iO ...

  10. python解无忧公主数学题108

    """ python解无忧公主数学题108回文.py 题目来源: http://mp.weixin.qq.com/s?__biz=MzI5ODEwMDQyNw==& ...