所以我有一个问题。目前我正在研究组装。我真的不想在其中编码,但它对我正在从事的一些 C/C++ 项目很有用。
我正在查看此页面:http://ref.x86asm.net/coder32.html,似乎有很多不同的说明变体。
喜欢:
mov eax, eax
不同于
mov 0xaddress, 0xaddress
为什么计算机不根据"参数"自己解释这些?
cpu 确实根据参数解释这些,尤其是在 x86 中。 有一个字节,一个操作数,作为您的文档,当然还有许多更好的文档显示操作数表以及它们映射到的内容。 基于操作数,它可能需要另一个字节(或更多),但是当它在初始操作数之后解析每个字节时,图片变得更加清晰,CPU应该做什么,这是一个mov,但是什么样的,好吧,它是一个寄存器寄存器,好吧,两个寄存器,最终得到一些指示每个寄存器的位数。 这是一个 mov,好吧,什么样的,寄存器,立即,然后是指示寄存器和立即的更多操作数。
但我们不认为这些是带有操作数的函数。 所以我们通常不会以这种方式编写汇编语言。 相反,汇编语言旨在缩小特定机器语言位的范围,以获得非常具体的指令。
mov ax,1234h
mov ah,byte ptr[ax]
如果我没记错的话,英特尔实际上可能具有不在乎位或其他功能,您可以在其中实现两种有效方式(请参阅 a86 文档还是 as86?
英特尔确实/确实有一个指令集(不是x86或相关),它确实具有基于函数的汇编语言,我不会说它是什么,但我只是搜索了一下,有合法和/或非法的课堂讲座等显示了其中一些语法。
alu[x,--,y,+,z]
可能故意类似于一个函数,即表示 x = y + z; 我认为您可以使用括号而不是括号,宏语言看起来也像函数
mymacro(w,x,y,z)
这些项目可以随心所欲地在宏中使用,就像 C 中的定义一样,宏只是按原样推送文本,因此您必须确保它符合要求。
alu[w,--,x,+,y]
alu[w,--,w,and,z]
我见过有人使用 C 作为汇编程序,这非常非常酷,非常容易实现汇编程序,因为 C 编译器负责所有解析
add(r0,r1);
sub(r2,r3);
并且您将后端链接/包含到您的主"程序">
#define r0 0
#define r1 1
#define r2 2
#define r3 3
void add ( unsigned int a, unsigned int b)
{
emit(0x4140|(ra<<3)|rb);
}
我不记得条件是如何工作的,我认为有类似的东西
label("hello");
...
bne("hello");
最后修补了转发引用...
可以用这样的方法在创纪录的时间内敲出一个汇编程序......但大多数人可能从未见过这一点,也没有尝试使用或实现它。
有些处理器是固定长度的指令,有些是可变的,变量更像是一个操作码,从中你计算出有多少操作码然后操作数。 固定长度仍然具有操作数字段/位,但基于此解释其余位,非常容易实现在单个时钟周期内建立的解码器,并不是说你不能为x86提供一个宽移位寄存器也在一个时钟中建立,但从历史上看,这不是它的工作方式,CISC倾向于微编码。
汇编语言由汇编程序定义,汇编程序解析它。 至于语法,这取决于该汇编程序的作者,只要您符合机器语言,您就可以制作任何您能想到的语法,没有任何理由不能制作一个功能类似于操作数的 x86 汇编器。
addrr(ax,bx); //mov ax,bx
movbptr(ah,bx); //mov ah,byte ptr bx
只要你能实现足够的指令是有用的,理想情况下是整个指令集。 理想情况下,每行创建一个特定的指令。 在历史的这个时刻,您将遇到的问题是找到此工具的用户/消费者。 几乎没有人编写纯粹的汇编语言,所以主要消费者是编译器,而那些已经有汇编语言作为输出,他们不必编写(像gas这样的现有语言)。