我对此非常生气,无法弄清楚为什么我的BEQ语句总是被执行。 程序应该替换位于内存中的char(RO中的地址)
_ should become +
C should become A
A should become B
B should become C
这是我到目前为止(对不起法国评论):
MOV R11, #0 ; Initialise le nombe de copie fait
MOV R10, #43 ; R10 = +
MOV R9, #'_' ; R9 = _
MOV R8, #'A' ; R8 = A
MOV R7, #'B' ; R7 = B
MOV R6, #'C' ; R6 = C
TOP:
LDRB R5, [R0, R11] ; Copie element X dans R5
CMP R5, R9
BEQ PLUS
CMP R5, R8
BEQ A
CMP R5, R7
BEQ B
CMP R5, R6
BEQ C
PLUS: ; Branchement si _
STRB R10, [R0, R11]
A: ; Branchement si A
STRB R8, [R0, R11]
B: ; Branchement si B
STRB R7, [R0, R11]
C: ; Branchement si C
STRB R6, [R0, R11]
ADDS R11, R11, #1 ; ++nbcopiefait
CMP R11, R1 ; Validation de la condition
BNE TOP
答案 0 :(得分:2)
显然不仅是C&#39 {s} switch()
让人感到困惑......
所以,你目前正在做的是相当于
for (size_t i = 0; i < n; i++)
{
switch(chararray[i])
{
default:
case '_': chararray[i] = '+';
case 'C': chararray[i] = 'A';
case 'A': chararray[i] = 'B';
case 'B': chararray[i] = 'C';
}
}
您在break;
之后错过了case
编辑,因为我似乎必须让它变得非常明显:
for (size_t i = 0; i < n; i++)
{
switch(chararray[i])
{
default:
break;
case '_': chararray[i] = '+';
break;
case 'C': chararray[i] = 'A';
break;
case 'A': chararray[i] = 'B';
break;
case 'B': chararray[i] = 'C';
break; //unnecessary, but I put it in for regularity
}
}
答案 1 :(得分:0)
要扩展EOF's answer,您可以通过逐个示例执行指令跟踪来查看正在发生的事情 - 调试器始终有帮助,但这很容易手动完成。让我们考虑几种不同的情况:
Instruction case char=='A' case char=='Z'
-------------------------------------------------------------------
...
LDRB R5, [R0, R11] executes, r5='A' executes, r5='Z'
CMP R5, R9 executes, flags=ne executes, flags=ne
BEQ PLUS flags!=eq, not taken flags!=eq, not taken
CMP R5, R8 executes, flags=eq executes, flags=ne
BEQ A flags==eq, taken flags!=eq, not taken
CMP R5, R7 / executes, flags=ne
BEQ B / flags!=eq, not taken
CMP R5, R6 / executes, flags=ne
BEQ C / flags!=eq, not taken
PLUS: STRB R10, [R0, R11] V executes: oops!
A: STRB R8, [R0, R11] executes executes: oops!
B: STRB R7, [R0, R11] executes: oops! executes: oops!
C: STRB R6, [R0, R11] executes: oops! executes: oops!
ADDS R11, R11, #1 executes executes
...
所以无论发生什么事,无论如何,一切都以“C”结束! (注意'A','B'和'C'有一个寄存器混合 - 如果你匹配r8,你跳转到存储r8等等。)实现等效的break
是一个确保说明的情况当不希望它们执行时跳过:
...
CMP R5, R6
BEQ C
B LOOP ; no match, skip everything
PLUS: STRB R10, [R0, R11]
B LOOP ; we've stored '_', skip 'B', 'C', and 'A'
A: STRB R7, [R0, R11]
B LOOP ; we've stored 'B', skip 'C' and 'A'
B: STRB R6, [R0, R11]
B LOOP ; we've stored 'C', skip 'A'
C: STRB R8, [R0, R11] ; nothing to skip, just fall through to the loop
LOOP: ADDS R11, R11, #1
...
但请注意,与大多数体系结构不同,ARM的条件执行适用于大多数指令。因此,给定少量简单例程(1-3条指令)的另一种方法是实际删除所有分支,并让条件执行处理它:
...
LDRB R5, [R0, R11]
CMP R5, R9
STRBEQ R10, [R0, R11]
CMP R5, R8
STRBEQ R7, [R0, R11]
CMP R5, R7
STRBEQ R6, [R0, R11]
CMP R5, R6
STRBEQ R8, [R0, R11]
ADDS R11, R11, #1
...
这样,一切都会被“执行”,但任何未通过条件检查的商店都不会做任何事情。