今天上课时刚刚上了第一堂课。讲师没有解释太多,因为这个想法是我们必须使用书籍来阅读装配的工作原理。我的编程背景是Python和C ++,并且希望将其组装起来,甚至考虑在代码中来回跳动,这是一种牺牲品。
谈论分支时,问题一直困扰着我,这在我的书中似乎没有任何解释。基本上,OP代码B +(EQ,PL等)根据条件和标志进行分支。例如,如果……即是什么,“ BEQ位置”将分支到“位置”。根据我的判断,它使用先前的指示来找出条件(在这种情况下,如果相等(Z = 1))。如果确实如此,那么BEQ会看前一条指令的返回值来评估EQ,例如,我如何做一个循环,使第一个R0(寄存器0)的值为0,然后再发生其他事情,最后我想一个条件分支,检查R0是否为零?
问题2: 我还注意到,如果您要执行某种功能:
WhileLoop:
MOV R0, R1
..bla bla bla
BEQ WhileLoop
我如何知道BEQ回到“ WhileLoop”?这是否意味着我做的每个功能都需要给它一个不同的名称。也许我不能正确理解功能。
请帮助。
答案 0 :(得分:1)
您需要阅读ARM文档。您的问题的答案就在那里。
是的,ARM使用标志。与使用标志的任何指令集一样,您需要检查您正在使用或希望使用的每条指令,或者为了获得一般性了解以了解它们是否修改了标志。例如,AND操作设置进位标志是否有意义?不,但是设置零标志有意义吗?当然,这很有用,或者有时他们的TST设置了零标志,而AND却没有,取决于体系结构。
与典型的基于标志的解决方案不同,ARM有一阵子扭曲了,您必须询问指令来设置标志。如果您发现
loop:
sub r0,#1
bne loop
不执行您想要的操作,因为根据书面内容(根据arm文档),减法不会触摸任何标志,尤其是我们正在测试的Z标志,但是...
loop:
subs r0,#1
bne loop
此代码,减法确实会碰到Z标志。
它允许类似
的事情 cmp r2,r3
moveq r1,#1
bxeq lr
mov r1,#0
bx lr
或者说
if(foo==1)
{
bar++;
}
您通常需要将其实现为
compare with 1
branch if not equal to skip
increment
skip:
所以您有一个管道,也许可以通过分支获取命中
但是
compare with 1
increment if equal
条件执行,条件位。
现在,对于完整尺寸的手臂指令来说,拇指指令是另外一回事了。
随着64位指令集aarch64的使用,整个有条件的东西都消失了,为执行条件而为每条指令烧掉4位是很痛苦的,还不够用。他们本来可以拥有32个通用寄存器,但可能更有用...
所以不确定您要问的功能是什么,首先使用汇编语言,您通常可以使用WhileLoop之类的标签。汇编程序将其转换为正确的指令,虽然Loop不是指令,但它基本上是一个地址,在这种情况下,汇编程序应使用您要求的指令并执行pc相对偏移(不使用固定地址,它会计算标签和beq之间有很多指令,并说如果相等,则向后跳转N条指令)。如果将beq放在某个标签上,并且该标签在另一个模块/对象中定义,则链接器随后必须修补该指令。
就功能而言,因此如果用C编写程序,并且要编写多个指令,是否需要使所有功能名称不同?是的实际上,汇编中没有函数之类的东西,有一些指令给人一种错觉,但它只是一个奇特的标签。但是代表功能的代码,如果要编写其中的7个,则需要为每个标签使用不同的标签。汇编语言与它无关。
gnu汇编程序具有一个有趣的功能,没有理由假定其他汇编语言支持(汇编语言由汇编程序,工具而不是目标(ARM指令集)定义),非常容易针对许多不同的示例进行演示指令集,易于编写的手臂装配,无法在所有受积极支持的装配商之间进行装配。因此,这是一个gnu汇编技巧,可能会或可能不会帮助您使用标签
1:
subs r0,#1
beq 1f
b 1b
1:
您通常只想执行bne,但这可以演示该功能。带有数字的标签是特殊的1f表示标签1:向前,因此下一个标签1:向下翻页。 1b表示1:向后,因此从这一点开始向上阅读页面以查找下一个1:因此您不必做
myfunction:
...
myfunction00:
...
myfunction01:
...
myfunction02:
...
因为您正在努力使中间标签难以处理填充和循环上的简单分支。
您可以选择是特征还是负担,因为它会养成可能特定于工具或不特定于工具的习惯。