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