如何在PIC​​24F汇编代码中实现循环

M S*_*gde 2 assembly instruction-set pic pic24 dspic

下面是以下C代码的反汇编:

268:                   while (Counter < 250)
269:                   {
270:                       Counter++;
271:                   }
Run Code Online (Sandbox Code Playgroud)

拆卸:

268:                   while (Counter < 250)
001B08  370003     BRA 0x1B10
001B10  90406E     MOV.B [W14+6], W0
001B12  404FE7     ADD.B W0, #0x7, [W15]
001B14  36FFFA     BRA LEU, 0x1B0A
269:                   {
270:                       Counter++;
001B0A  90406E     MOV.B [W14+6], W0
001B0C  E84000     INC.B W0, W0
001B0E  984760     MOV.B W0, [W14+6]
271:                   }
272:                   
273:                   // call foo
274:                   foo(LAT, 4, Set, &Code);
001B16  203F20     MOV #0x3F2, W0
001B18  40000E     ADD W0, W14, W0
001B1A  780180     MOV W0, W3
001B1C  B3C012     MOV.B #0x1, W2
001B1E  B3C041     MOV.B #0x4, W1
001B20  202C40     MOV #0x2C4, W0
001B22  0709C7     RCALL foo
Run Code Online (Sandbox Code Playgroud)

无法理解while循环是如何实现的.假设[W14 + 6]指的Counter是存储的位置RAM .

注意:为PIC24FV32KA304生成的代码

Jam*_*mes 6

它已将您的代码的代码顺序更改为:

GOTO A
B:  Counter++;
A:  if (Counter <= 249) GOTO B
Run Code Online (Sandbox Code Playgroud)

这是带有我评论的重新排序的程序集:

001B08  370003     BRA 0x1B10               // GOTO A
                         B: Counter++;
001B0A  90406E     MOV.B [W14+6], W0        // Copy Counter to W0
001B0C  E84000     INC.B W0, W0             // Increment W0
001B0E  984760     MOV.B W0, [W14+6]        // Put W0 back in Counter
                         A:  if (Counter <= 249) GOTO B
001B10  90406E     MOV.B [W14+6], W0        // Get counter to W0
001B12  404FE7     ADD.B W0, #0x7, [W15]    // Add 7 in modulo 256.
                                            // This is the same as subtracting 249
001B14  36FFFA     BRA LEU, 0x1B0A          // if result <= 0 GOTO B
                                            // else just drop through to code below
Run Code Online (Sandbox Code Playgroud)

BRA LEU是这里的关键循环指令.如果L ess比或E qual U签名,则表示BRA nch.这意味着如果前一条指令留下C = 0或Z = 1,则采用分支.

容易混淆的一个细节是,加法后C进位标志.但是,如果在这个例子中,我们想把它ADD当作一个减法,那么你应该把它not(C)视为借用.这就是为什么BRA LEU在C = 0时采用分支的原因.