Reputation: 79
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
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:
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
-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
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