当前位置:  技术问答>linux和unix

请教各位,Linux下的汇编怎么搞?

    来源: 互联网  发布时间:2015-03-18

    本文导语:  哪位高手指点一下,怎样在Linux下用汇编开发,用什么工具,什么样的汇编语法等等,谢了! | gcc中的:(计算a+b) int main() {   int a,b,c;   a=23;   b=45;   asm ("movl %1,%%eax;         movl %2,...

哪位高手指点一下,怎样在Linux下用汇编开发,用什么工具,什么样的汇编语法等等,谢了!

|
gcc中的:(计算a+b)
int main() {
  int a,b,c;
  a=23;
  b=45;
  asm ("movl %1,%%eax;
        movl %2,%%ebx;
        addl %%ebx,%%eax;
        movl %%eax,%0"
        :"=g"(c)
        :"g"(a),"g"(b)
        :"%eax","%ebx");
  printf("c=%dn",c);
}

|
我就说的通俗一点
取/引用寄存器里的值要: %eax 如 movl %eax,%ebx
将寄存器里的值作为指针取指针指向的值要: (%eax).
取指针值的一般形式为: _偏移(_基址,_索引,步长)==_基址+_索引*步长+_偏移;_偏移为变量或常量.
取/引用变量或常量的值要: $0x7c00,$_variable. 如 movl $0x7c00,%eax
取变量或常量指针所指向的值为: 0x7c00,_variableptr。

其实观察不难发现:取指针所指向的值不管是常量,变量还是寄存器其实都是
取指针值的一般形式的特殊形式而已。

|
你要为什么cpu写程序,你总的有一个该cpu编译程序吧,有好多cpu提供了linux下的编译工具

然后你就用vi编辑,编译,查错...... 就可以啦。当然,你也可以为你的汇编程序写一个开发工具,一个仿真器等等,呵呵,高手啦

我在linux下作过1024,6502,arm等等的ap,大概就是这么一个过程

|
linux下面一般用三种工具
as86: 简单的intel汇编指令
nasm: 支持比较复杂的intel汇编(流行)
gas/as: 支持at&t的汇编指令,linux内核中的汇编就是用它

|
一般来说有两种方法,一种方法是用GCC的内嵌汇编,具体信息可以
info ar
另一种方法是用NASM,可以man nasm

|
贴一个老文档,去年写的,大家看看有问题没有 :)
在c代码中嵌入汇编
1.简介
本文介绍在c代码中嵌入汇编语言的方法,所有的方法仅对gcc(Gnu C Compiler)有效。由于作者是在一台pc上进行的实验,所以例子中如果未加说明,所有的汇编代码均为x86汇编。本文的唯一参考资料就是gcc Manual,其中的5.36小节介绍了在c中嵌入汇编的办法。
2.如何在c中嵌入汇编代码
2.1.最简单的情形
在gcc里有一个asm表达式,用于实现嵌入汇编。就像这样
asm("xor %%eax, %%eax");
这个汇编指令的作用是吧eax寄存器清零,你也许注意到这些代码和我们常见的x86汇编代码有些不同,的确,gcc使用的汇编格式是AT&T格式而不是DOS下常见的Intel格式,它们之间主要区别有:AT&T格式的寄存器使用%标志开头,例如Intel格式中的EAX在这里写作%eax;AT&T格式的目的操作数是后一个而不像Intel格式那样是前一个,比如:
asm("movl %%eax, %%ebx");
是将eax寄存器的值移到ebx。另外还有一些区别,比如内存地址的表示方法等等,详情可以参考DJGPP FAQ里的Coverting between Intel ASM syntax and AT&T syntax。
另外还要注意%号在asm表达式里是特殊字符,所以%eax前面要再加一个%号进行转义,这样就成了"%%eax"这样的寄存器表示方法,如果你用的是Sparc之类的cpu,寄存器使用"r1""r5"之类的表达式,就不需要累赘的%号了。
为了比较易读,多行的汇编代码可以写成这样
asm("xor %%eax, %%eax
movl -20(%%ebp), %%ebx
sub %%ebx, %%eax");
不过在最新的gcc-3系列里一个字符串写了一行以上是会引发一个warning的,让人看了不舒服,这样写就不会了:
asm("xor %%eax, %%eax nt"
"movl -20(%%ebp), %%ebx nt"
"sub %%ebx, %%eax");
n就是换行,t是tab对齐,这下明白了吧 :)
2.2.使用c中定义的变量
先给出一个例子:
int foo;
asm("movl %%eax, %0"
: "=g" (foo));
在asm()中,在冒号分隔符后面声明你的变量,括号中是变量名(foo),"=g"表示这是一个作为输出的整型变量,如果变量是作为输入的话,就要放在第二个括号分隔符后面,象这样:
int foo1,foo2;
asm("movl %1, %%eax nt"
"movl %%eax, %0"
: "=g" (foo1)
: "g" (foo2));
程序是把foo2的内容赋给foo1。从这个例子可以看到,变量在汇编语言里被引用的时候表示符是该变量在asm()里被声明的位置,foo1在asm()里首先声明,所以是%0,foo2紧接着所以是%1。"g"表示是一个整型,前面有"="号说明这是一个作为输出的变量(也就是被写的),没有"="号就说明是作为输入的变量。别的被支持的类型还有"r"(寄存器变量),"m"(内存变量),"f"(浮点变量)等等,更多的表示可以参考gcc manual 20.7.1 。
2.3.避免寄存器冲突
如果你在汇编中显式的使用寄存器,编译器会注意不会在上下文中造成冲突,但是有一些指令是不会显式的使用寄存器的,例如cpuid这条指令,它运行以后会改变%eax,%ebx,%ecx,%edx的值,但是这些寄存器不会在代码里出现,因此编译器不会为你避开这个冲突,如果你直接调用这个指令,可能就会造成你的代码core dump!一个笨笨的办法是自己保护寄存器,调用cpuid之前先将四个寄存器push到栈里,运行了cpuid之后将值保存,再pop这四个寄存器。当然这样很影响代码的效率。其实解决的办法很简单,在asm()的第三个冒号后面声明那些需要保护的寄存器就可以了,像这样:
asm("cpuid"
:
:
:"%eax","%ebx","%ecx","%edx");
注意在这里一个"%"号就好了,这样编译器就会小心的避开这些寄存器的冲突。

|
type "info as" and you will get all information.

    
 
 

您可能感兴趣的文章:

  • 请教,X86汇编转AT&T汇编,急急
  • 100分请教高手如何反汇编arm raw文件
  • 请教一个函数入口处的汇编问题(压栈问题)
  • 100分请教高手一个Linux内核ARM汇编的问题
  • 请教,AT&T格式汇编问题。
  • 请教一个 AT&T 汇编问题
  • 请教:linux 2.6内核汇编中的.size起什么作用?
  • 请教大多数的汇编指令周期数
  • 请教高人:AT&T汇编语言中把.byte .word .long的问题?
  • 请教Linux下pgadmin3-1.0.2的编译和安装!!高分请教!
  • 各位大虾,请教装了REDHAT9操作系统后,启动时无法引导到LINUX,请教该如何解决啊
  • 向linux达人请教linux下5.1声道测试工具
  • 请教一下,如果想在linux下开发java,选哪个版本的linux好一点
  • 小弟想请教,如果现在不像装linux了怎样把linux的分区改回ntfs格式的?
  • 请教:linux启动盘和一张盘的linux有何区别?
  • 请教linux高手,在Linux
  • 在linux下面怎么安程序啊?我刚裝了一个 linux,下了一个迅雷安装程序,可是不知道怎么安装啊?真心请教。
  • 初次接触linux,关于linux 用户权限问题请教!
  • 请教linux 下的adsl拨号问题.
  • 【请教】LINUX 下SNMP的MIB开发
  • 请教象我这样的硬盘应如何安装Linux,我昨天试装了,但有问题。(老问题了,也看了前面的帖子,但还是来请教,请多指教)
  • 各位大狭!小弟初学Linux,请各位列举学Linux的网站,留下QQ,Email以向各位请教!!!多谢了!!!
  • 菜鸟请教Linux
  • 高手看过来:请教如何在移动硬盘上安装Linux?
  • c/c++开源软件 iis7站长之家
  • 请教风河 linux内核 如何配置使之支持xwindows?
  • 请教大家一下,linux运维方面的书应该读什么?
  • 请教:如何直接使用RedHat Linux 9的ISO文件安装Linux?
  • 我的linux装不上啊???请教高手
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 请教,请教,这个问题是为什么????
  • 请教本地硬盘安装问题请教本地硬盘安装问题
  • ■请教■请教redhat最基本的问题!
  • 请教一个 shell 问题,我用下面这个 shell 语句总是失败,请教
  • 高分请教,各位大侠,请教一个问题,理论高手请进??谢谢
  • 请教,请教,,,一定要看!!一定要看!!
  • 请教高手,小弟打印width=1500,height=600(A3纸)的Applet,在预览中是该区域是黑的,打印出来也是黑的,请教高手解决一下
  • :请教高手,小弟打印width=1500,height=600(A3纸)的Applet,在预览中是该区域是黑的,打印出来也是黑的,请教高手解决一下
  • 请教这种循环的执行过程
  • 请教两个redhat9问题
  • 请教如何在指定目录下查找包含指定文字的文件
  • 请教局域网中如何通过ip地址得到主机名
  • 请教kdevelop的问题
  • 请教,如何用虚拟订机安装liux
  • 请教一个opengl的问题
  • 请教unix常用命令命令问题
  • 请教两个shell
  • 请教高手:如何用gnome/gtk编写托盘程序
  • 请教semop()函数的用法、含义
  • 请教个,关于C编译器参数CFLAGS的问题(真诚请教,分不够了全部送出)


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3