【问题标题】:what is mean by machine level code and how to view it?机器级代码是什么意思以及如何查看它?
【发布时间】:2020-06-08 10:07:42
【问题描述】:

我们知道机器级代码是 0,1(二进制)的形式。现在,在 c 编程中,如果 cmd 是 -

gcc -c ok.c

其中 ok.c 是一个在 c 中打印“hi”的简单程序。 现在,创建了一个文件 ok.o,它应该是机器级指令。ok.o 文件的内容类似于-

^@^L^@UH��H�=^@^@^@^@�^@^@^@^@�^@^@^@^@�]�hi^@^@GCC: (Debian 9.3.0-10) 9.3.0^@^@^@^@^@^@^@^@^T^@^@^@^@^@^@^@^AzR^@^Ax^P^A^[^L^G^H�^A^@^@^\^@^@^@^\^@^@^@^@^@^@^@^X^@^@^@^@A^N^P�^BC
^FS^L^G^H^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^D^@��^@^@^@^@^@^@^@^@^@^

等等很多这样的角色。这个输出是什么意思,如果这是机器级指令,那么为什么它不是二进制数字(0,1)的形式,即 1000110111111010101....(类似的东西)我怎么能看到二进制类型的代码?如果我在某处错了,请也纠正我。 谢谢

【问题讨论】:

  • 是二进制码。记事本(或您正在使用的任何东西)正试图将其解读为文本。它可能会假设一些编码并尝试从二进制代码中生成符号。你基本上得到了垃圾。
  • .o 文件并不全是机器码。里面还有其他东西。总的来说,该文件是 ELF 格式(至少在 Linux 上)。机器代码不是最终形式,因为绝对地址还没有被解析。当 .o 文件链接到可执行文件时,这些问题就会得到解决。
  • 您需要的是一个十六进制编辑器。我认为它不会给你太多,但至少它可以查看原始数据
  • objdump -s ok.o 将以十六进制和可打印 ASCII 字符的可打印形式显示文件内容。
  • 使用 objdump 来查看解码

标签: c gcc compilation compiler-optimization machine-code


【解决方案1】:

你可以这样做来产生一个汇编文件(ok.s):

gcc -S ok.c

ok.s 文件是人类可读的文本文件(如您的 .c 文件)。它将是机器指令的列表。这就是人类“查看”机器代码的方式。

有关这些说明的含义的更多信息,请参阅: https://en.wikipedia.org/wiki/X86_assembly_language

当您查看二进制 .o 文件时,您将其视为文本(其中 8 个(或更多)二进制位将根据其值形成人类可见的字符,这就是为什么它看起来像一堆随机字符的原因.

【讨论】:

  • 汇编代码不是机器代码。机器代码是一种由计算机直接执行的二进制文件组成的语言,而汇编语言是一种低级编程语言,需要称为汇编程序的软件将其转换为机器代码。 more here...
【解决方案2】:

给定一个简单的 C 程序,例如

#include <stdio.h>
int main( void ) { printf( "This is a test\n" ); return 0; }

如果您想查看实际的机器码(不仅仅是汇编程序,还有实际的操作码和操作数),您有几个选择:

  • 正常构建文件:
    gcc -o simple -std=c11 -pedantic -Wall -Werror simple.c
    然后使用带有-d 选项(objdump -d simple)的objdump 命令,您将获得类似于此的列表:
    00000000004004c7 <main>:
      4004c7:   55                      push   %rbp
      4004c8:   48 89 e5                mov    %rsp,%rbp
      4004cb:   bf 60 05 40 00          mov    $0x400560,%edi
      4004d0:   e8 1b ff ff ff          callq  4003f0 
      4004d5:   b8 00 00 00 00          mov    $0x0,%eax
      4004da:   5d                      pop    %rbp
      4004db:   c3                      retq   
      4004dc:   0f 1f 40 00             nopl   0x0(%rax)
      ^         ^                       ^
      |         |                       |
      |         |                       +---- assembler
      |         +---------------------------- machine code
      +-------------------------------------- instruction address
    
  • 使用-Wa,-aldh=<em>listing-file</em> 选项构建文件以生成程序集和机器代码列表:
    gcc -o simple -std=c11 -pedantic -Wall -Werror -Wa,-aldh=simple.lst simple.c
    这将创建一个类似于以下内容的列表文件:
    GAS LISTING /tmp/ccAMmy8W.s             page 1
    
    
       1                    .file   "simple.c"
       2                    .text
       3                    .section    .rodata
       4                .LC0:
       5 0000 54686973      .string "This is a test"
       5      20697320 
       5      61207465 
       5      737400
       6                    .text
       7                    .globl  main
       9                main:
      10                .LFB0:
      11                    .cfi_startproc
      12 0000 55            pushq   %rbp
      13                    .cfi_def_cfa_offset 16
      14                    .cfi_offset 6, -16
      15 0001 4889E5        movq    %rsp, %rbp
      16                    .cfi_def_cfa_register 6
      17 0004 BF000000      movl    $.LC0, %edi
      17      00
      18 0009 E8000000      call    puts
      18      00
      19 000e B8000000      movl    $0, %eax
      19      00
      20 0013 5D            popq    %rbp
      21                    .cfi_def_cfa 7, 8
      22 0014 C3            ret
      23                    .cfi_endproc
      24                .LFE0:
      26                    .ident  "GCC: (GNU) 7.3.1 20180712 (Red Hat 7.3.1-6)"
      27                    .section    .note.GNU-stack,"",@progbits
      ^  ^    ^             ^
      |  |    |             |
      |  |    |             +---- assembler
      |  |    +------------------ machine code
      |  +----------------------- instruction offset
      +-------------------------- instruction number
    
    如果您使用 -g 选项构建,您将获得与生成的输出交错的原始源代码:
    GAS LISTING /tmp/ccJ7L1rJ.s          page 1
    
    
       1                    .file   "simple.c"
       2                    .text
       3                .Ltext0:
       4                    .section    .rodata
       5                .LC0:
       6 0000 54686973      .string "This is a test"
       6      20697320 
       6      61207465 
       6      737400
       7                    .text
       8                    .globl  main
      10                main:
      11                .LFB0:
      12                    .file 1 "simple.c"
       1:simple.c      **** #include <stdio.h>
       2:simple.c      **** 
       3:simple.c      **** int main( void )
       4:simple.c      **** {
      13                    .loc 1 4 0
      14                    .cfi_startproc
      15 0000 55            pushq   %rbp
      16                    .cfi_def_cfa_offset 16
      17                    .cfi_offset 6, -16
      18 0001 4889E5        movq    %rsp, %rbp
      19                    .cfi_def_cfa_register 6
       5:simple.c      ****   printf( "This is a test\n" );
      20                    .loc 1 5 0
      21 0004 BF000000      movl    $.LC0, %edi
      21      00
      22 0009 E8000000      call    puts
      22      00
       6:simple.c      ****   return 0;
      23                    .loc 1 6 0
      24 000e B8000000      movl    $0, %eax
      24      00
       7:simple.c      **** }
      25                    .loc 1 7 0
      26 0013 5D            popq    %rbp
      27                    .cfi_def_cfa 7, 8
      28 0014 C3            ret
      29                    .cfi_endproc
      30                .LFE0:
      32                .Letext0:
      33                    .file 2 "/usr/lib/gcc/x86_64-redhat-linux/7/include/stddef.h"
      34                    .file 3 "/usr/include/bits/types.h"
      35                    .file 4 "/usr/include/libio.h"
      36                    .file 5 "/usr/include/stdio.h"
    

【讨论】:

    猜你喜欢
    • 2012-07-22
    • 2010-11-22
    • 2015-02-02
    • 2012-06-29
    • 2012-09-12
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多