汇编语言和机器语言是一一对应的吗? 汇编语言是cpu生产厂商规定的还是编译器厂商规定的?

        汇编语言和机器语言是一一对应的吗? 一些人认为,是的。 一些人认为, 不是的。 其实, 两种认为都对。
        为什么说两种看法都对? 我们首先来看看这个问题:汇编语言是cpu生产厂商规定的还是编译器厂商规定的?
  
       cpu是硬件, 无非就是一些电路元件和开关的组合。 编程的本质, 就是在不同时刻拨弄那些开关,形成不同的逻辑值。 显然,我们不能用手去拨弄那些开关, 而是采取先把开关存起来, 然后输入到cpu中。 开关其实就是二进制状态, 所以,把开关存起来的意思是把二进制存起来, 这些二进制就是机器语言。从最开始的直接操作开关, 到现在的编写二进制存储起来, 是一个很大的进步, 是从硬变软的进步。至此, cpu厂商只要把电路设计合理,并且告诉别人怎么编写二进制机器代码,就行了。 任务完成, cpu正常工作。
 
       可是, 机器语言编码很不方便, 这一点我深有感悟。玩过自制cpu, 玩过机器语言编程, 我只想说, 那真不是人该干的活。 于是, 一种助记符就出现了。 以intel的cpu为例,intel在生产cpu后, 提供了操作该cpu的机器语言规范, 这就足够了。 但是, intel为了让买家更方便, 就强推了一种助记符号, 这就是intel汇编语言规范。
 

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

int main()
{
    int a = 1;
    int b = 2;
    int c = 0;
    c = a - b;
    return 0;
}

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

1:    int main()
2:    {
00401010   push        ebp
00401011   mov         ebp,esp
00401013   sub         esp,4Ch
00401016   push        ebx
00401017   push        esi
00401018   push        edi
00401019   lea         edi,[ebp-4Ch]
0040101C   mov         ecx,13h
00401021   mov         eax,0CCCCCCCCh
00401026   rep stos    dword ptr [edi]
3:        int a = 1;
00401028   mov         dword ptr [ebp-4],1
4:        int b = 2;
0040102F   mov         dword ptr [ebp-8],2
5:        int c = 0;
00401036   mov         dword ptr [ebp-0Ch],0
6:        c = a - b;
0040103D   mov         eax,dword ptr [ebp-4]
00401040   sub         eax,dword ptr [ebp-8]
00401043   mov         dword ptr [ebp-0Ch],eax
7:        return 0;
00401046   xor         eax,eax
8:    }
00401048   pop         edi
00401049   pop         esi
0040104A   pop         ebx
0040104B   mov         esp,ebp
0040104D   pop         ebp
0040104E   ret

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

        .file   "test.cpp"
        .text
        .globl  main
        .type   main, @function
main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    $1, -12(%rbp)
        movl    $2, -8(%rbp)
        movl    $0, -4(%rbp)
        movl    -12(%rbp), %eax
        subl    -8(%rbp), %eax
        movl    %eax, -4(%rbp)
        movl    $0, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
        .ident  "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609"
        .section        .note.GNU-stack,"",@progbits

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


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

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



猜你喜欢

转载自blog.csdn.net/stpeace/article/details/80199870