什么是机器级代码,如何查看?

问题描述 投票:0回答:1

我们知道机器级代码的形式是0,1(二进制)。现在,在c语言编程中,使用gcc编写一个程序,如果cmd是--。

gcc -c ok.c

其中,ok.c是一个简单的程序,在c中打印 "hi".现在,创建了一个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......(类似的东西),而且我怎么能看到二进制的那种代码?请,也纠正我,如果我错了的地方.谢谢。

c gcc compilation compiler-optimization machine-code
1个回答
2
投票

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

gcc -S ok.c

ok.s文件是一个人类可读的文本文件(就像你的.c文件)。它将是一个机器指令的列表。这就是人类如何 "查看 "机器代码。

关于这些指令的更多信息,请参见:https:/en.wikipedia.orgwikiX86_assembly_language(汇编语言)

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


1
投票

给定一个简单的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
    然后使用... objdump 命令与 -d 选项 (objdump -d simple),你会得到一个类似于这样的列表。
    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=listing-file 选项来生成一个汇编和机器代码的列表。
    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"
    
© www.soinside.com 2019 - 2024. All rights reserved.