请选择 进入手机版 | 继续访问电脑版

学JAVA网

 找回密码
 立即注册

[linux] 汇编语言和机器语言是一一对应的吗?

[复制链接]
发表于 2018-8-6 15:15:39 |显示全部楼层
汇编语言和机器语言是一一对应的吗? 汇编语言是cpu生产厂商规定的还是编译器厂商规定的?

汇编语言和机器语言是一一对应的吗? 一些人认为,是的。 一些人认为, 不是的。 其实, 两种认为都对。
        为什么说两种看法都对? 我们首先来看看这个问题:汇编语言是cpu生产厂商规定的还是编译器厂商规定的?
  
       cpu是硬件, 无非就是一些电路元件和开关的组合。 编程的本质, 就是在不同时刻拨弄那些开关,形成不同的逻辑值。 显然,我们不能用手去拨弄那些开关, 而是采取先把开关存起来, 然后输入到cpu中。 开关其实就是二进制状态, 所以,把开关存起来的意思是把二进制存起来, 这些二进制就是机器语言。从最开始的直接操作开关, 到现在的编写二进制存储起来, 是一个很大的进步, 是从硬变软的进步。至此, cpu厂商只要把电路设计合理,并且告诉别人怎么编写二进制机器代码,就行了。 任务完成, cpu正常工作。

       可是, 机器语言编码很不方便, 这一点我深有感悟。玩过自制cpu, 玩过机器语言编程, 我只想说, 那真不是人该干的活。 于是, 一种助记符就出现了。 以intel的cpu为例,intel在生产cpu后, 提供了操作该cpu的机器语言规范, 这就足够了。 但是, intel为了让买家更方便, 就强推了一种助记符号, 这就是intel汇编语言规范。

        来看一个简单的C/C++源程序:

  1. int main()
  2. {
  3.     int a = 1;
  4.     int b = 2;
  5.     int c = 0;
  6.     c = a - b;
  7.     return 0;
  8. }
复制代码

         如果采用intel汇编规范, 转化后的汇编语言为(如下是微软的VC++6.0环境, 微软遵从了intel汇编语言规范):

  1. 1:    int main()
  2. 2:    {
  3. 00401010   push        ebp
  4. 00401011   mov         ebp,esp
  5. 00401013   sub         esp,4Ch
  6. 00401016   push        ebx
  7. 00401017   push        esi
  8. 00401018   push        edi
  9. 00401019   lea         edi,[ebp-4Ch]
  10. 0040101C   mov         ecx,13h
  11. 00401021   mov         eax,0CCCCCCCCh
  12. 00401026   rep stos    dword ptr [edi]
  13. 3:        int a = 1;
  14. 00401028   mov         dword ptr [ebp-4],1
  15. 4:        int b = 2;
  16. 0040102F   mov         dword ptr [ebp-8],2
  17. 5:        int c = 0;
  18. 00401036   mov         dword ptr [ebp-0Ch],0
  19. 6:        c = a - b;
  20. 0040103D   mov         eax,dword ptr [ebp-4]
  21. 00401040   sub         eax,dword ptr [ebp-8]
  22. 00401043   mov         dword ptr [ebp-0Ch],eax
  23. 7:        return 0;
  24. 00401046   xor         eax,eax
  25. 8:    }
  26. 00401048   pop         edi
  27. 00401049   pop         esi
  28. 0040104A   pop         ebx
  29. 0040104B   mov         esp,ebp
  30. 0040104D   pop         ebp
  31. 0040104E   ret
复制代码

      可是,还有个牛逼的组织叫AT&T,  他的历史比intel更早, 所以, 他很可能采用另外的习惯。 即使intel推荐如上规范,AT&T可能鸟都不鸟一下, 而是采用另外一种自己的规范, 这叫AT&T汇编语言规范。 用g++编译下上面的源程序, 得到的汇编语言为:

  1.         .file   "test.cpp"
  2.         .text
  3.         .globl  main
  4.         .type   main, @function
  5. main:
  6. .LFB0:
  7.         .cfi_startproc
  8.         pushq   %rbp
  9.         .cfi_def_cfa_offset 16
  10.         .cfi_offset 6, -16
  11.         movq    %rsp, %rbp
  12.         .cfi_def_cfa_register 6
  13.         movl    $1, -12(%rbp)
  14.         movl    $2, -8(%rbp)
  15.         movl    $0, -4(%rbp)
  16.         movl    -12(%rbp), %eax
  17.         subl    -8(%rbp), %eax
  18.         movl    %eax, -4(%rbp)
  19.         movl    $0, %eax
  20.         popq    %rbp
  21.         .cfi_def_cfa 7, 8
  22.         ret
  23.         .cfi_endproc
  24. .LFE0:
  25.         .size   main, .-main
  26.         .ident  "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609"
  27.         .section        .note.GNU-stack,"",@progbits
复制代码

       可见, 形式完全不一致。也是牛逼了。


       无论是intel汇编语言规范, 还是AT&T汇编语言规范, 都没有关系, 最重要的是, 保证汇编语言经转换后, 能实现相同逻辑功能的机器语言。 如果你愿意, 你也可以基于intel cpu来定义你自己的汇编语言规范。

       回到最开始的问题: 汇编语言和机器语言是一一对应的吗?  现在, 你可以说, 在同一汇编规范下, 他们是一一对应的。 如果考虑到不同的汇编语言规范, 他们就不是一一对应的了。 在多数场合, 笼统地说,  汇编语言和机器语言是一一对应的。


您需要登录后才可以回帖 登录 | 立即注册

Archiver|手机版|学JAVA网

GMT+8, 2018-10-20 01:14 , Processed in 0.154238 second(s), 21 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

Copyright © 2015-2018 xuejava网 / 鲁ICP备17054568号-1
回顶部