views:

58

answers:

1

For example:

        .text
        .align 2
        .global main
        .equ val,0x4712         # 16-bit binary code for 0x4712: 0100 0111 0001 0010
                                # Program code starts now
main:                           # This label must be main:, not MAIN: 
        movi r16,val            # WHAT WOULD THIS LINE BE IN BINARY?
        movi r17,0
loop:   addi r17,r17,1
        subi r16,r16,1 
        bne  r16,r0,loop
stop:   br   stop
.end 
+1  A: 

You mean, by hand?

By hand, you grab the instruction set sheet for your microprocessor, understand your addressing modes, and other data representation issues, and then convert that to something convenient, like a hexadecimal notation.

Then you would need to get that information in to the devices memory, using some device specific process (file from disk, file from serial line, keyed in from a front panel with a bunch a switches).

Obviously, there can be all sorts of tool chain issues that you'll need to figure out to get your binary into a machine. If you're just doing it for laughs, hexadecimal, a pencil, and a legal pad have suited many for years.

Edit --

You have to know several things.

First, the op codes, and along with the op codes, you need to know the addressing modes.

Consider this 6502:

LDA #$00
LDA $00
LDA $1234

Those are three different instructions on the 6502.

The first loads the Accumulator (A) with $00, 0 in hex. The # symbol tells the assembler that you're using the "immediate" addressing mode (the 6502 has 13 total addressing modes).

The second load the Accumulator with the value of the memory location located at address $0000. On the 6502, it has a "zero page" mode, so it can more easily access memory from the first page of memory (addresses $0000-$00FF).

The third loads the Accumulator with the value of the memory location located at address $1234. This is absolute addressing, simply specifying the actual address of the memory you are interested in.

I highlight this example because, at a glance, all three of these look the same. But in truth, they all compile to 3 distinct instructions, or opcodes. So, it's important to understand what your assembly is telling you so that you can select the correct opcode for your processor.

Now, if you look at a opcode guide for the 6502, and look up the LDA instruction, you'll see the different, binary values for each instruction.

So, in this case you would get:

$A9 $00
$A5 $00
$AD $12 $34

That's the binary (in hex) representation of those 3 instructions.

The first, $A9, is for the "immediate" addressing mode, the second, $A5, for Zero Page addressing, and finally $AD for Absolute.

Also note that following the operands, are the arguments. For the 6502, they just follow in the byte stream. Different processors do different things. Note, that for the Absolute, we have 2 bytes, $12 and $34, each representing half of the total, 16 bit address. I believe this is correct, that the Most Significant Byte of the address comes first, but it might be reversed ($A9 $34 $12).

So, that's the fundamental of assembling by hand.

Other things to note are issues like what location the assembly will be loaded at. That will affect values for things like your labels.

In 6502:

label:  LDA #$00
        JMP label

If your assembly is starting at the address $1000, this this will assemble to:

$A9 $00
$4C $10 $00

If your assembly is starting at address $5555 then:

$A9 $00
$4C $55 $55

See, the JMP (Jump) instruction ($4C) needs an address to jump to, and the label in your assembly is relative to its location in the program. Conveniently, in this case, the label is at the very beginning. But you can see how the address is coded in to the final machine code.

6502 is EASY (really easy) assembly. Modern processors, well, aren't. The modern assemblers do a lot of work for you, and you have more complicated CPUs with larger instruction sets, and things like alignment issues -- these are all missing from the 6502. But as a hand assembler, you're responsible for all of those nuances.

Your microprocessor manual is supposed to tell you these nuances. But with the modern complicated CPUs, its likely non-trivial to do and learn.

Don't necessarily want to deter you from this, but be aware, it may well be a lot of work.

But this is the essence of what you need to do.

Will Hartung
There is a hexadecimal notation already. But I can't get it right. For example: 0x40000 = 00000100000100011100010010000100 and I don't even get how they got it.
jdnhldn
no, 0x40000 = 01000000000000000000. binary 00000100000100011100010010000100 = 0x0411c484.
Chris Dodd