I kinda want to code in binary just for the fun of it. But I have no idea how to compile my code. Anyone know how?

Recommended Answers

All 12 Replies

Learn assembler.

As WaltP already said, what you are looking for is not a compiler but something called an "Assembler". Assembly is the language that CPUs speak, every Assembly statment gets turned into a CPU processing instruction. The Assembler turns the Assembly text into instructions.

However, I think that assembly is quite hard. You can have a look at it if you use gcc by using the "--save-temps" command line switch.

As an example I have used g++ on Mac to turn some C++ code into Assembly. C++ code:

#include <iostream>

int main(int argc, char *argv[]) {
	std::cout << "Hello, World!" << std::endl;
	return 0;
}

Assembly code:

.mod_init_func
	.align 3
	.quad	__GLOBAL__I_main
	.section __TEXT,__textcoal_nt,coalesced,pure_instructions
.globl __ZSt3minImERKT_S2_S2_
	.weak_definition __ZSt3minImERKT_S2_S2_
__ZSt3minImERKT_S2_S2_:
LFB1478:
	pushq	%rbp
LCFI0:
	movq	%rsp, %rbp
LCFI1:
	movq	%rdi, -8(%rbp)
	movq	%rsi, -16(%rbp)
	movq	-16(%rbp), %rax
	movq	(%rax), %rdx
	movq	-8(%rbp), %rax
	movq	(%rax), %rax
	cmpq	%rax, %rdx
	jae	L2
	movq	-16(%rbp), %rax
	movq	%rax, -24(%rbp)
	jmp	L4
L2:
	movq	-8(%rbp), %rax
	movq	%rax, -24(%rbp)
L4:
	movq	-24(%rbp), %rax
	leave
	ret
LFE1478:
	.text
__ZStL17__verify_groupingPKcmRKSs:
LFB1407:
	pushq	%rbp
LCFI2:
	movq	%rsp, %rbp
LCFI3:
	pushq	%rbx
LCFI4:
	subq	$88, %rsp
LCFI5:
	movq	%rdi, -72(%rbp)
	movq	%rsi, -80(%rbp)
	movq	%rdx, -88(%rbp)
	movq	-88(%rbp), %rdi
	call	__ZNKSs4sizeEv
	decq	%rax
	movq	%rax, -32(%rbp)
	movq	-80(%rbp), %rax
	decq	%rax
	movq	%rax, -48(%rbp)
	leaq	-48(%rbp), %rsi
	leaq	-32(%rbp), %rdi
	call	__ZSt3minImERKT_S2_S2_
	movq	(%rax), %rax
	movq	%rax, -40(%rbp)
	movq	-32(%rbp), %rax
	movq	%rax, -56(%rbp)
	movb	$1, -17(%rbp)
	movq	$0, -64(%rbp)
	jmp	L7
L8:
	movq	-56(%rbp), %rsi
	movq	-88(%rbp), %rdi
	call	__ZNKSsixEm
	movzbl	(%rax), %edx
	movq	-64(%rbp), %rax
	addq	-72(%rbp), %rax
	movzbl	(%rax), %eax
	cmpb	%al, %dl
	sete	%al
	movb	%al, -17(%rbp)
	decq	-56(%rbp)
	incq	-64(%rbp)
L7:
	movq	-64(%rbp), %rax
	cmpq	-40(%rbp), %rax
	jae	L11
	cmpb	$0, -17(%rbp)
	jne	L8
	jmp	L11
L12:
	movq	-56(%rbp), %rsi
	movq	-88(%rbp), %rdi
	call	__ZNKSsixEm
	movzbl	(%rax), %edx
	movq	-40(%rbp), %rax
	addq	-72(%rbp), %rax
	movzbl	(%rax), %eax
	cmpb	%al, %dl
	sete	%al
	movb	%al, -17(%rbp)
	decq	-56(%rbp)
L11:
	cmpq	$0, -56(%rbp)
	je	L13
	cmpb	$0, -17(%rbp)
	jne	L12
L13:
	movq	-40(%rbp), %rax
	addq	-72(%rbp), %rax
	movzbl	(%rax), %eax
	testb	%al, %al
	jle	L15
	movzbl	-17(%rbp), %ebx
	movq	-88(%rbp), %rdi
	movl	$0, %esi
	call	__ZNKSsixEm
	movzbl	(%rax), %edx
	movq	-40(%rbp), %rax
	addq	-72(%rbp), %rax
	movzbl	(%rax), %eax
	cmpb	%al, %dl
	setle	%al
	movzbl	%al, %eax
	andl	%ebx, %eax
	testl	%eax, %eax
	setne	%al
	movb	%al, -17(%rbp)
L15:
	movzbl	-17(%rbp), %eax
	addq	$88, %rsp
	popq	%rbx
	leave
	ret
LFE1407:
	.cstring
LC0:
	.ascii "Hello, World!\0"
	.text
.globl _main
_main:
LFB1477:
	pushq	%rbp
LCFI6:
	movq	%rsp, %rbp
LCFI7:
	subq	$16, %rsp
LCFI8:
	movl	%edi, -4(%rbp)
	movq	%rsi, -16(%rbp)
	leaq	LC0(%rip), %rsi
	movq	__ZSt4cout@GOTPCREL(%rip), %rdi
	call	__ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
	movq	%rax, %rdi
	movq	__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GOTPCREL(%rip), %rsi
	call	__ZNSolsEPFRSoS_E
	movl	$0, %eax
	leave
	ret
LFE1477:
	.section __TEXT,__StaticInit,regular,pure_instructions
__Z41__static_initialization_and_destruction_0ii:
LFB1490:
	pushq	%rbp
LCFI9:
	movq	%rsp, %rbp
LCFI10:
	subq	$16, %rsp
LCFI11:
	movl	%edi, -4(%rbp)
	movl	%esi, -8(%rbp)
	cmpl	$1, -4(%rbp)
	jne	L24
	cmpl	$65535, -8(%rbp)
	jne	L24
	leaq	__ZStL8__ioinit(%rip), %rdi
	call	__ZNSt8ios_base4InitC1Ev
	movq	___dso_handle@GOTPCREL(%rip), %rdx
	movl	$0, %esi
	leaq	___tcf_0(%rip), %rdi
	call	___cxa_atexit
L24:
	leave
	ret
LFE1490:
__GLOBAL__I_main:
LFB1492:
	pushq	%rbp
LCFI12:
	movq	%rsp, %rbp
LCFI13:
	movl	$65535, %esi
	movl	$1, %edi
	call	__Z41__static_initialization_and_destruction_0ii
	leave
	ret
LFE1492:
	.text
___tcf_0:
LFB1491:
	pushq	%rbp
LCFI14:
	movq	%rsp, %rbp
LCFI15:
	subq	$16, %rsp
LCFI16:
	movq	%rdi, -8(%rbp)
	leaq	__ZStL8__ioinit(%rip), %rdi
	call	__ZNSt8ios_base4InitD1Ev
	leave
	ret
LFE1491:
.lcomm __ZStL8__ioinit,1,0
	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
	.set L$set$0,LECIE1-LSCIE1
	.long L$set$0
LSCIE1:
	.long	0x0
	.byte	0x1
	.ascii "zPR\0"
	.byte	0x1
	.byte	0x78
	.byte	0x10
	.byte	0x6
	.byte	0x9b
	.long	___gxx_personality_v0+4@GOTPCREL
	.byte	0x10
	.byte	0xc
	.byte	0x7
	.byte	0x8
	.byte	0x90
	.byte	0x1
	.align 3
LECIE1:
.globl __ZSt3minImERKT_S2_S2_.eh
	.weak_definition __ZSt3minImERKT_S2_S2_.eh
__ZSt3minImERKT_S2_S2_.eh:
LSFDE1:
	.set L$set$1,LEFDE1-LASFDE1
	.long L$set$1
LASFDE1:
	.long	LASFDE1-EH_frame1
	.quad	LFB1478-.
	.set L$set$2,LFE1478-LFB1478
	.quad L$set$2
	.byte	0x0
	.byte	0x4
	.set L$set$3,LCFI0-LFB1478
	.long L$set$3
	.byte	0xe
	.byte	0x10
	.byte	0x86
	.byte	0x2
	.byte	0x4
	.set L$set$4,LCFI1-LCFI0
	.long L$set$4
	.byte	0xd
	.byte	0x6
	.align 3
LEFDE1:
__ZStL17__verify_groupingPKcmRKSs.eh:
LSFDE3:
	.set L$set$5,LEFDE3-LASFDE3
	.long L$set$5
LASFDE3:
	.long	LASFDE3-EH_frame1
	.quad	LFB1407-.
	.set L$set$6,LFE1407-LFB1407
	.quad L$set$6
	.byte	0x0
	.byte	0x4
	.set L$set$7,LCFI2-LFB1407
	.long L$set$7
	.byte	0xe
	.byte	0x10
	.byte	0x86
	.byte	0x2
	.byte	0x4
	.set L$set$8,LCFI3-LCFI2
	.long L$set$8
	.byte	0xd
	.byte	0x6
	.byte	0x4
	.set L$set$9,LCFI5-LCFI3
	.long L$set$9
	.byte	0x83
	.byte	0x3
	.align 3
LEFDE3:
.globl _main.eh
_main.eh:
LSFDE5:
	.set L$set$10,LEFDE5-LASFDE5
	.long L$set$10
LASFDE5:
	.long	LASFDE5-EH_frame1
	.quad	LFB1477-.
	.set L$set$11,LFE1477-LFB1477
	.quad L$set$11
	.byte	0x0
	.byte	0x4
	.set L$set$12,LCFI6-LFB1477
	.long L$set$12
	.byte	0xe
	.byte	0x10
	.byte	0x86
	.byte	0x2
	.byte	0x4
	.set L$set$13,LCFI7-LCFI6
	.long L$set$13
	.byte	0xd
	.byte	0x6
	.align 3
LEFDE5:
__Z41__static_initialization_and_destruction_0ii.eh:
LSFDE7:
	.set L$set$14,LEFDE7-LASFDE7
	.long L$set$14
LASFDE7:
	.long	LASFDE7-EH_frame1
	.quad	LFB1490-.
	.set L$set$15,LFE1490-LFB1490
	.quad L$set$15
	.byte	0x0
	.byte	0x4
	.set L$set$16,LCFI9-LFB1490
	.long L$set$16
	.byte	0xe
	.byte	0x10
	.byte	0x86
	.byte	0x2
	.byte	0x4
	.set L$set$17,LCFI10-LCFI9
	.long L$set$17
	.byte	0xd
	.byte	0x6
	.align 3
LEFDE7:
__GLOBAL__I_main.eh:
LSFDE9:
	.set L$set$18,LEFDE9-LASFDE9
	.long L$set$18
LASFDE9:
	.long	LASFDE9-EH_frame1
	.quad	LFB1492-.
	.set L$set$19,LFE1492-LFB1492
	.quad L$set$19
	.byte	0x0
	.byte	0x4
	.set L$set$20,LCFI12-LFB1492
	.long L$set$20
	.byte	0xe
	.byte	0x10
	.byte	0x86
	.byte	0x2
	.byte	0x4
	.set L$set$21,LCFI13-LCFI12
	.long L$set$21
	.byte	0xd
	.byte	0x6
	.align 3
LEFDE9:
___tcf_0.eh:
LSFDE11:
	.set L$set$22,LEFDE11-LASFDE11
	.long L$set$22
LASFDE11:
	.long	LASFDE11-EH_frame1
	.quad	LFB1491-.
	.set L$set$23,LFE1491-LFB1491
	.quad L$set$23
	.byte	0x0
	.byte	0x4
	.set L$set$24,LCFI14-LFB1491
	.long L$set$24
	.byte	0xe
	.byte	0x10
	.byte	0x86
	.byte	0x2
	.byte	0x4
	.set L$set$25,LCFI15-LCFI14
	.long L$set$25
	.byte	0xd
	.byte	0x6
	.align 3
LEFDE11:
	.constructor
	.destructor
	.align 1
	.subsections_via_symbols

Of course, this is machine generated assembly, so it's quite difficult to understand. But yeah, you can see that it's quite hard ;).

I've also been looking to program in binary. But I'm not exactly sure that Assembler is the right thing for me...

I don't understand what we're trying to do here.

Is it a macho thing? Do we want to show that were's so masochistic that we can write our programs directly in binary? Or is there some specific binary data that needs to be put in a file for which no existing compiler seems ideal?

Member Avatar for lrirwin

The only time I've ever needed to actually input binary code was when the boot block on an old Data General system failed. - Had to boot entering octal instructions from a set of switches on the front panel -- Really glad those days are gone!

'binary compiler' makes no sense. Binary code is the result of the compilation process. You can code directly in binary (or octal or hex or decimal, just different number bases) if you have a suitable editor (hex, or whatever) and knowledge of the target machine's instruction set.

While an assembler does generally map instruction mnemonics 1-for-1 to machine instructions, it also has symbolic references to memory lcations, macros (procedure abstraction) and pseudo-operations for defining strings and other kinds of data. So it works at a higher level than binary.

If you are trying to make binary code execute on a 'real world' computer with an operating system, you also need to know how it represents load module information, external references, etc. It becomes very time consuming very quickly. Even something as simple as an arduino benefits from a high level language. But it's a good place to start playing with machine code.

That said, there's nothing like putting in a boot sequence through the front panel swithches (see lrlrwin post above... that took me back to the day of Nova 4 and IMSAI.

I hope you have fun with this.

The only time I ever had to program in binary was on an GE SPPC (stored program process controller) micro computer from 1979-1982. There were no symbolic debuggers (or debuggers of any type) at that time. To debug, you hand assembled some debug code then patched it into unused memory via front panel toggle switches. You then added it to your existing code by toggling in a JMP statement. It was ugly but faster than cross compiling from an IBM mainframe, generating paper tape then transferring that to cassette tape. Did I mention that the generating station that housed the computer was 600 miles North of Winnipeg (several hours by small plane)? Each actual recompile would have taken two days and cost several thousand dollars.

The dark ages are gone. I can't see any reason to program in Assembler let alone binary. But I have to say the fishing up there was awesome.

Boy this takes me back to the 1960's -- entering code on buttons or switches. You can get a simlar experience these days with an Arduino and Raspberry Pie computer, I guess.

Pardon the thread necromancy, but I can't help but mention a famous bit of hacker lore regarding a programmer working in pure binary (well, hex actually, but still) in the 1960s - The Story of Mel, A Real Programmer.

(And yes, Mel Kaye was a real person; the story is apparently as true as any such legends go.)

Actually, I would say that the question is somewhat misphrased.

Programming in Assembler is generally the lowest level used, even for VERY heavy systems programming tasks (e.g., vector primitives, machine diagnostics).

If one is experimenting with hand assembly of code (aka "writing code in binary") the tool used to import the code from the form in which it is stored to main memory is not a compiler, but a loader of some form.

You do not need an assembler, or any other prog to program in binary, except a hex editor. Hexadecimal is baslically the same as binary, but it takes much less space. For example:

binary hex
0001    1
0010    2
0011    3
0100    4
1111    F

Then just rename the file .exe (if it's on Windows), and it will run.

But instead of people telling you not to try to program in binary, or calling you masochistic, I think you need to explore it for yourself, and understand it.
Assembly is usually as low-level as programming ever goes.

Assembly is usually much easier then binary, but it still has 1-to-1 correspondance in instructions.
So for example in C, you would type

int a = 3;

in assembly you would type

mov a, 3

and in binary it may be 110101010101010101111
But the difference is that in C, or any other language 1 instruction may actually be A LOT of different binary or assembly instructions, but each assembly instruction corresponds exactly to a binary instruction.

If you try Assembly, and learn it, and you are still interested in binary, you can write assemblers and linkers that translate assembly, into binary.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.