vikram singh
vikram singh

Reputation: 79

what is mean by machine level code and how to view it?

We know machine level code are in form of 0,1 (binary). Now, in c programming using gcc for a program if cmd is -

gcc -c ok.c

where ok.c is a simple program to print "hi" in c. Now, a file ok.o is created which is supposed to be machine level instructions.The content of ok.o file is something like-

^@^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^@��^@^@^@^@^@^@^@^@^@^

and so on lots of character like this. what does this output mean and if this is machine level instruction then why it is not in form of binary digit(0,1) i.e 1000110111111010101....(something like that) and also how can i see binary kind of code ? Please , also correct me if I am wrong somewhere. Thanks

Upvotes: 0

Views: 1037

Answers (2)

John Bode
John Bode

Reputation: 123458

Given a simple C program like

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

if you want to look at actual machine code (not just the assembler, but the actual opcodes and operands), you have a couple of options:

  • Build the file as normal:
    gcc -o simple -std=c11 -pedantic -Wall -Werror simple.c
    Then use the objdump command with the -d option (objdump -d simple), and you'll get a listing similar to this:
    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
    
  • Build the file with the -Wa,-aldh=listing-file option to generate a listing of assembly and machine code:
    gcc -o simple -std=c11 -pedantic -Wall -Werror -Wa,-aldh=simple.lst simple.c
    which will create a listing file similar to this:
    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
    
    If you build with the -g option, you'll get the original source code interleaved with the generated output:
    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"
    

Upvotes: 2

Secto Kia
Secto Kia

Reputation: 969

You can do this to produce an assembly file (ok.s):

gcc -S ok.c

The ok.s file be human readable text file (like your .c file). It will be a listing of the machine instructions. This is how a human 'views' the machine code.

For more information about what those instructions mean see: https://en.wikipedia.org/wiki/X86_assembly_language

When you view your binary .o file you are viewing it as text (where 8 (or more)) binary bits will be forming a human viewable character depending on their value, which is why it looks like a bunch of random characters.

Upvotes: 2

Related Questions