Is it possible to program in binary?
A friend of mine told me he knows someone who can program in binary. I've never heard of someone programming in binary and a few quick Google searches didn't return anything useful. So I figured I'd turn to the SO community. Does anyone have any info on programming in binary and if possible maybe a quick Hello World example.
Of course. It's more commonly called machine code. It's basically assembly language without the mnemonic devices. Someone who knows assembly very well could program in machine code with additional effort, referring to opcode listings (e.g. x86) as needed.
Would I do it? No. Even assembly is only useful in rare circumstances, and there's no reason (beside demonstrating your skills) to reject the assembler's help.
Since you asked about hello world, you should check out this article. He shows how he wrote, then optimized, an x86 ELF program to output it. It was originally written in nasm then modified in a hex editor.
It's very much possible to memorize machine code equivalent of assembly instructions. Actually, when writing code in assembly language, one often happens to see hex code through machine code monitors, disassemblers, assembly listings, etc. As a result, over time some instructions can be memorized in their hex form without any extra effort.
In the picture an 6502 ROM monitor is seen, where hex code and assembly mnemonics are shown side by side.
Second skill you're going to need is to transform hex code into binary which is quite easy with a trick I'll explain in a bit.
Think of the following instructions:
OPCODE HEX
LDA #imm 0xA9 imm
STA adr 0x85 adr
STA (adr),Y 0x91 adr
LDY #imm 0xA0 imm
With above opcodes memorized only, we can write the following machine code using only pen and paper:
0xA9 0x00
0x85 0x01
0xA9 0x02
0x85 0x02
0xA0 0x00
0xA9 0x01
0x91 0x01
Actually the above is the following assembly code in mnemonic form:
LDA #00
STA $01
LDA #02
STA $02
LDY #00
LDA #01
STA ($01), Y
The above code puts a white pixel at the top-left corner of screen in 6502asm.com assembler/emulator, go ahead and try it out!
Now the trick for converting hexadecimals into binary and vice versa is to work it out only for nibbles (4-bit values).
First, remember how to convert binary into decimal. Every time you see 1, multiply that by its binary power. E.g. 101 would be 4 + 0 + 1 = 5. It can be visualized like this:
1 1 1 1 --> binary points
| | | |
v v v v
8 + 4 + 2 + 1
| | | +---> 2^0 * 1 Ex: 13 is 8 + 4 + 0 + 1
| | +-------> 2^1 * 1 1 1 0 1 -> 1101 (0xD)
| +-----------> 2^2 * 1 Ex: 7 is 0 + 4 + 2 + 1
+---------------> 2^3 * 1 0 1 1 1 -> 0111 (0x7)
With this in mind, and well practiced, the following should be possible:
LDA #00 -> 0xA9 0x00 -> 1010 1001 0000 0000
STA $01 -> 0x85 0x01 -> 1000 0101 0000 0001
LDA #02 -> 0xA9 0x02 -> 1010 1001 0000 0010
STA $02 -> 0x85 0x02 -> 1000 0101 0000 0010
LDY #00 -> 0xA0 0x00 -> 1010 0000 0000 0000
LDA #01 -> 0xA9 0x01 -> 1010 1001 0000 0001
STA ($01),Y -> 0x91 0x01 -> 1001 0001 0000 0001
With some retro computing spirit, motivation and fun, we could actually have written the entire code in binary without writing down the intermediate steps.
On a related note, Paul Allen coded a boot loader for Altair 8800 with pen and paper on an airplane, and possibly had to translate it to binary also with pen and paper: https://www.youtube.com/watch?v=2wEyqJnhec8
There isn't much call for it any more, but it has been done. There was a time when code could be entered into a system in binary from the front console. It was error prone.
I used to have a very short uudecoe program encoded in ASCII which could be prefixed to a UUEncoded file. The resulting file would be self-extracting and could be emailed around. I would expect the machine code was hand done. I can't find it, and don't have a use for it even if I could.
Well of course you can write the binary for the machine code and then enter the machine code via your hex key pad into your computer. I have put together a computer based on the TMS1100.
A simple program to display 5 on the hex LED would be 0001000 0000101 0000001 written in binary converted to machine code that would be 8 5 1 . This program would then run and display 5 on the LED.
You could follow this procedure for far more complex programs using the TMS1100 and I guess programming in binary.
Actually, I think this is very satisfying and rewarding if you are interested in mathematics and programming.
For the brave of heart: you can try getting a MikeOS floppy image and running the monitor.bin program. It allows you to enter hexadecimal opcodes by hand and execute them. For example (as stated on the docs), entering the following instructions:
BE0790 E8FD6F C3 4D00$ will produce a single M on the screen.
There are some esoteric programming languages. They are used as experiments, and are rather impractical, but one, called BrainF**k (yes, it is actually a real thing) uses eight different characters to modify byte values. Those kind of languages are about as close as you can get.
Related
This is a question and answer from my operating system's textbook:
Question:
A certain computer provides its users with a virtual-memory space of 232 bytes.
The computer has 218 bytes of physical memory. The virtual memory is implemented by paging,
and the page size is 4096 bytes. A user process generates the virtual address 11123456.
Explain how the system establishes the corresponding physical location.
Distinguish between software and hardware operations.
Answer:
The virtual address in binary form is
0001 0001 0001 0010 0011 0100 0101 0110
When I plug "11123456" into a decimal to binary converter (like here: https://www.rapidtables.com/convert/number/decimal-to-binary.html), this is the result: 101010011011101100000000
which differs from the book answer.
Also, when I manually convert using a method like here: https://indepth.dev/the-simple-math-behind-decimal-binary-conversion-algorithms/
I still get something different.
I'm just confused how that virtual address was converted into binary form......
Thanks!
You think
11123456
is a decimal number but it isn't. The Computer representation of number is ever binary, octal or hexadecimal. In this case is Hexadecimal. If you convert the above number from hexadecimal to binary form you obtain the result:
0001 0001 0001 0010 0011 0100 0101 0110
Explanation:
Hexadecimal -> Binary
1 -> 0001
2 -> 0010
3 -> 0011
4 -> 0100
5 -> 0101
6 -> 0110
...
I am learning about Computer architecture through the MIPS instructions. I have a question which is:
Memory at 0x10000000 contains 0x80
Register $5 contains 0x10000000
What is put in register $8 after lb $8,0($5) is executed?
I was thinking when the load byte is called, it will take the 8 bits of 0x80[10000000] from the 0x10000000 address and load it into the first 8 bits of the $8 register and fill the remaining bits with zeros making the answer to be 00000080. But the correct answer listed is FFFFFF80. I am not sure if I understand it. Can anybody help explain it?
The instruction you mention here is lb which loads a one byte into a register by sign-extending the byte to the word size. This means if the most significant bit is set to 1 it will fill the remaining 24 bits with 1 as well. This is done to preserve the twos-complement value of the byte in a 32 bit representation.
If your byte would be 0100 1010 the sign-extend would fill it with 0 as
0000 000... 0100 1010.
If your byte would be 1011 0101 the sign-extend would fill it with 1 as
1111 111... 1011 0101.
To avoid this and always pad the byte with 0 you can use the alternative lbu instruction which does not perform a sign-extend but pads the byte with 0 instead.
This preserves the unsigned value of the byte since twos-complement is not involved for those.
I want to measure current fuel level inside my car's fuel tank using OBD2 bluetooth/USB adapter.
When i try to query that PID i got following data as "NO DATA" while at the same time i can check other PIDS like RPM and all data comes fine.
I have small python program which reads its but i am unable to get it.
import serial
#ser = serial.Serial('COM12',38400,timeout=1)
#ser.write("01 2F \r")
#speed_hex = ser.readline().split(' ')
#print speed_hex
#convert hex to decprint ("SpeedHex",speed_hex)
#speed = float(int('0x'+speed_hex[3],0))
#print ('Speed',speed,'Km/h')
ser1 = serial.Serial("COM12",38400,timeout=1)
#ser1.write("ATZ \r")
#ser1.write("ATE0 \r")
#ser1.write("ATL0 \r")
#ser1.write("ATH1 \r")
#ser1.write("ATSP 5 \r")
ser1.write("01 0C \r")
fuel_hex= ser1.readline()
print fuel_hex
#convert to hex to decprint ("FuelHex",fuel_hex)
#fuel = float(int('0x'+fuel_hex[3],0))
#print ("Fuel in Per",fuel)
Can any one suggest here how to get fuel level which is their inside in car at this current time. As i can see in my panel with bar sign.
In order to get all the available PIDs in a vehicle, you have to request the following PIDs at first exactly like you ask the rpm of the vehicle:
0x00, 0x20, 0x40, ....0x80 and so on.
For instance when you request PID 0x00 the ECU will return you 4 bytes which means if it supports PIDs from 0x01 - 0x20. Each byte has 8 bits in total of 32 bits which is exactly from PID 0x01 to PID 0x20. Now it is time to parse the data. If each bit is 1 it means the ECU will support and 0 no support. It is your duty to do some bitwise operations to translate these bits:
Also you can look out this Wikipedia link which shows in graphics!
byte 1 bit 1 : availability of PID 0x01
byte 1 bit 2 : availability of PID 0x02
byte 1 bit 3 : availability of PID ox03
....
byte 4 bit 7 : availability of PID 0x1F
byte 4 bit 8 : availability of PID 0x20 --> Here the ECU tells you if support any PIDs in next 32 PIDs. If it is 0, you do not need to check anymore!
After parsing and gathering all the supported PIDs, then you can have a roadmap to calculate or check each PIDs you want. Do not forget many of conversion rates a formulas in wikipedia is wrong due to the complexity of calculations. You have to read the ISO 15031 part 5 and do NOT forget ECU only gives you the emissions-related diagnostics and not all the data.
For the following entries, what instructions do they represent respectively?
Binary: 00000001110001011000100000100001
Hexadecimal: 144FFF9D
I'm completely lost on what I'm doing here - searching online has produced a bunch of results that make very little sense to me, but what I've gathered is I'm basically supposed to match up the numbers to their appropriate instructions/registers, but how exactly do I know what those are? Where can I find a comprehensive list? How do I know whether it's an R I or J format function?
The first 6 bits (it is easier to work in binary) are the opcode, from which you can determine how to interpret the rest. This site should get you started: http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html
Update: Calling the first 6 bits the opcode is (to be too kind) misleading, but it is enough to tell you how to interpret the rest of the instruction; you may need to look elsewhere (typically at the end of the instruction) for the complete determination of the opcode.
There are 3 Type of MIPS Instructions:
R_type: Opcode must be 000000 (the first 6 bits) and with last 6 bits we can know what is the correct instruction
I_type
j_type
In this case, we have a R-type MIPS instruction and thus :
Opcode rs rt rd shamt funct
000000 01110 00101 10001 00000 100001
addu $s1 , $t6 , $a1
I have been trying to format binary opcodes for Motorola 68000, but I keep finding that it's not possible to encode both the destination memory address, instruction designation and addressing mode/size, and data value to be copied to the address bus for memory-mapped I/O.
For the Sega Genesis' Video Display Processor I am attempting to write to the control port which is memory mapped at C00004 in the Genesis' memory map.
C0004 is 1100 0000 0000 0000 0000 0100 in binary, or three bytes. The value I'm writing is 87, which the VDP recognizes as 8787 in VDP register #7. The issue I'm having is figuring out how to encode 32-bits worth of data, e.g. the instruction prefix designation move.b, value 87, which is #$87, and the destination memory address C00004 for MMIO re-routing to the correct VDP port on the way to the VDP.
Altogether it looks like this:
move.b #$87, $00C00004,
which loosely translates into not four, but four bytes and a nibble(36-bits to be exact!)
0001 1000 0111 1100 0000 0000 0000 0000 0100
Since Motorola 68000 will only parse 32-bits when working down to microcode, how is it possible to encode the required information if there's not enough space(and within the same instruction)?
Perhaps I'm understanding this incorrectly?
I know this is beyond the level most programmers would anticipate, but I'm hoping someone around can break this down for me and explain how this encoding scheme would work.
Your instruction, move.b #$87, $$00C00004 ought to encode to
0001111001111100 0000000010000111 00000000110000000000000000000100
(or similar; I'm not sure about the order of the operands).
The first 16-bit word can be broken down thusly:
The first four bits say that this is a move.b instruction.
The next six bits say that the destination addressing mode is an absolute 32-bit address.
The last six bits say that the source operand is immediate.
After that follows instruction extension words with the operands. The first is 16 bits for the immediate data, and the last 32 bits are for the address. (Might be the other way around.)
For more information, see http://www.freescale.com/files/archives/doc/ref_manual/M68000PRM.pdf