在程序集中使用分支命令(主要是BNE和BEQ )时感到困惑。因此,我必须为伪代码编写一个汇编代码:
X = 5, Y = 10, Z = 15
if X != 4 && Y == 10 || Z = 20
A = X + Y - 2
else R = Z - 5 + X我正在编码在Keil uVision5的ARM皮质M0加法(如果这是需要的信息)在它的低寄存器,这是R0-R7为这个特定的板。
我知道如何编写if else语句本身,但我主要问的是如何处理代码的OR部分。显而易见的X!=4为真,Y==10为真,然后检查Z = 20是否为false,所以我将首先检查X!=4是否为假,使用BNE标签跳转以检查Y,使用BEQ检查Z,这是假的,但由于等式已经为真,所以我会跳到A=X+Y-2的BNE endif语句
然后在中间没有标签在它前面,我会写其他的语句,让汇编程序去,如果第一个BNE标签是错误的..?
A EQU 0x2000000
R EQU 0x2000004
X EQU 0x2000008
Y EQU 0x200000C
Z EQU 0x2000010
LDR R7, =X
LDR R0, [R7]
ADD R0, #5 ; X = 5 in R0
CMP R0, #4 ; Compare X != 4
BNE jumpToY
jumpToY
LDR R7, =Y
LDR R1, [R7] ; Y = 10 in R1
CMP R1, #10 ; Compare Y == 10
BEQ jumpToZ
jumpToZ
etc...发布于 2015-05-06 20:56:57
asm一般用于使用由一条指令设置的标志的处理器,然后是分支或跳转条件指令。在设置标志的条件下,在分支/跳转之前的某个点,例如,在本例中,比较会执行此操作。条件指令上的分支的工作方式是,如果条件为true,则分支到该地址的方式与goto在C中的工作方式完全相同。如果条件不为真,则不为真。
if(x!=4) goto label0;
label2:
if(z==20) goto label1;
R = Z - 5 + X;
goto done;
label0:
if(y!=10) goto label2:
...
done:所以从上面如果x不是4,那么我们分支到label0,做那里的事情,如果它是4,那么我们继续做如果z==20,然后重新聚焦在z==20上,如果z==20,然后去label1,继续做数学。
在汇编中,这将类似于
ldr r0,=X
ldr r0,[r0]
cmp r0,#4
bne label0
ldr r2,=Z
ldr r2,[r2]
cmp r2,#20
beq label1
sub r2,#5
add r0,r2
ldr r2,=X
str r0,[r2]
b done
label0:
ldr r1,=Y
ldr r1,[r1]
cmp r1,#10
bne label2:
...
done:我在树枝后面放了空位,没有什么特别的理由。在第一个bne label0上,如果发生这种情况,那么我们接下来执行标签0之后的内容,如果设置了相等的标志,则加载y地址,然后不分支,我们继续执行Z地址的加载。
就覆盖逻辑路径而言,对于X!=4 Y==10和Z==20中的每一个,可能为自己创建一个真值表,结果要么是R=,要么是A=,然后您可以在最坏的情况下逐字执行真值表(8组比较)或缩小真值表,down...and一直优化到您满意为止。
最终,您希望A=代码具有到函数末尾的分支,而R=代码也希望分支到函数的末尾,然后根据您的真值表和实现创建到A=或R=代码的路径,但您必须点击其中的一个。
编辑:
注意你的前三行看上去不对
LDR R7, =X
LDR R0, [R7]
ADD R0, #5 ; X = 5 in R0这并不是将X设置为5,正如您的注释所暗示的那样,它将5添加到X,所以不管您添加了什么X。
如果您想实现这个X= 5,Y= 10,Z= 15
ldr r1,=X
mov r0,#5
str r0,[r1]
ldr r1,=Y
mov r0,#10
str r0,[r1]
ldr r1,=Z
mov r0,#15
str r0,[r1]然后得到x并比较它
LDR R7, =X
LDR R0, [R7]
CMP R0, #4 ; Compare X != 4发布于 2015-05-06 20:41:05
想想你是如何在头脑中评估逻辑条件的。如果你想要A或者B,你就不需要考虑B,如果你想要A和B,你没有A,那么计算B就没有意义了。
有一些纯粹主义者认为,你应该评估这两种条件,然后对结果进行逻辑比较:计算A、计算B和/或计算结果。
幸运的是,工程方法赢了:
对于A和B(假设BEQ为"true"):
Calculate A
BNE fail
Calculate B
BNE fail
success:
...
RET/JMP somewhere ; Don't drop through into fail
fail:
...对于A或B(同样,假设BEQ为"true"):
Calculate A
BEQ success
Calculate B
BNE fail
success:
...
RET/JMP somewhere ; Don't drop through into fail
fail:
...发布于 2015-05-06 20:43:22
A EQU 0x2000000
R EQU 0x2000004
X EQU 0x2000008
Y EQU 0x200000C
Z EQU 0x2000010在这里,您可以看到有条件的指令,以防止额外的跳跃。我们首先检查前2种情况,然后默认为或情况。注意,我们还必须跳过其他代码,以防止这两个代码的执行。还注意到我们掉到了其他情况下,也是为了防止额外的跳跃。
; These could be loaded with a singl LDM instruction instead.
LDR R7, =X
LDR R0, [R7]
LDR R7, =Y
LDR R0, [R7]
LDR R7, =Z
LDR R2, [R7]
CMP R0,#5
CMPEQ R1,#10
BEQ FirstCase
CMP R2,#5
BEQ FirstCase
;... Fall Through
ElseCase:
...
j RestOfCode
FirstCase:
...
RestOfCode:请注意,我在盲人中编码了这一点,这对任何语言来说都是一件危险的事情,ASM更是如此。它应该演示如何处理和/或您想要看到的情况。
您还可以将代码放入C编译器并检查输出,因为它也将显示工作代码。
https://stackoverflow.com/questions/30086526
复制相似问题