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
Run Code Online (Sandbox Code Playgroud)
Wil*_*ung 21
你的意思是,手工?
您可以手动获取微处理器的指令集表,了解寻址模式以及其他数据表示问题,然后将其转换为方便的内容,如十六进制表示法.
然后,您需要使用某些特定于设备的进程(来自磁盘的文件,来自串行线路的文件,从带有开关的前面板键入)将信息输入到设备存储器中.
显然,您可能需要弄清楚各种工具链问题,以便将二进制文件放入计算机中.如果你只是为笑,十六进制,一支铅笔和一个合法的垫子做了多年的适应.
编辑 -
你必须知道几件事.
首先,操作码和操作码需要知道寻址模式.
考虑这个6502:
LDA #$00
LDA $00
LDA $1234
Run Code Online (Sandbox Code Playgroud)
这些是6502上的三个不同说明.
第一个加载累加器(A),其中$ 00,0为十六进制.#符号告诉汇编器你正在使用"立即"寻址模式(6502有13种总寻址模式).
第二个加载累加器,内存位置的值位于地址$ 0000.在6502上,它具有"零页面"模式,因此它可以更容易地从内存的第一页访问内存(地址$ 0000- $ 00FF).
第三个加载累加器,其内存位置的值位于地址$ 1234.这是绝对寻址,只需指定您感兴趣的内存的实际地址即可.
我强调这个例子,因为一眼就看出所有这三个看起来都是一样的.但实际上,它们都编译为3个不同的指令或操作码.因此,了解程序集告诉您的内容非常重要,这样您就可以为处理器选择正确的操作码.
现在,如果您查看6502 的操作码指南,并查找LDA指令,您将看到每条指令的不同二进制值.
所以,在这种情况下你会得到:
$A9 $00
$A5 $00
$AD $12 $34
Run Code Online (Sandbox Code Playgroud)
这是这3条指令的二进制(十六进制)表示.
第一个,$ A9,用于"立即"寻址模式,第二个,$ A5,用于零页面寻址,最后是AD,用于绝对.
还要注意,在操作数之后是参数.对于6502,它们只是跟随字节流.不同处理器做不同的事情.注意,对于Absolute,我们有2个字节,12美元和34美元,每个字节代表总数的一半,16位地址.我认为这是正确的,地址的最重要字节是第一位的,但它可能会被逆转($ A $ 34 $ 12 $ 12).
所以,这是手工组装的基础.
其他需要注意的事项是装配件的位置等问题.这会影响标签之类的值.
在6502:
label: LDA #$00
JMP label
Run Code Online (Sandbox Code Playgroud)
如果您的程序集从地址$ 1000开始,这将汇总到:
$A9 $00
$4C $10 $00
Run Code Online (Sandbox Code Playgroud)
如果您的程序集从地址$ 5555开始,那么:
$A9 $00
$4C $55 $55
Run Code Online (Sandbox Code Playgroud)
请参阅JMP(跳转)指令($ 4C)需要跳转到的地址,并且程序集中的标签相对于其在程序中的位置.方便地,在这种情况下,标签是最开始的.但是您可以看到地址如何编码到最终的机器代码中.
6502很容易(非常简单)组装.现代处理器,不是.现代的汇编程序为你做了很多工作,你有更复杂的CPU和更大的指令集,以及对齐问题 - 6502中都缺少这些.但是作为手工汇编程序,你负责所有的那些细微差别.
您的微处理器手册应该告诉您这些细微差别.但是,对于现代复杂的CPU来说,它很可能是非常重要的.
不一定要阻止你,但要注意,这可能是很多工作.
但这是你需要做的事情的本质.