2013-12-16 80 views
0

我完全陌生的彙編語言,剛剛買了一個覆盆子pi。我知道我可以使用一個操作系統,並開始用python等編程,但我想深入瞭解一下。由於我的覆盆子pi沒有到達,我無法測試asm代碼。在課程OK03中,我看了解擴展解決方案(download),我試圖自己理解它,但我遇到了這個問題:爲什麼gpioAddr在最後(再次)str'ed到pinFunc?我參加了main.s爲例,第一次調用把我的意見:「烘烤Pi:OK03」 - 不理解功能

pinNum .req r0 
pinFunc .req r1 
mov pinNum,#16 
mov pinFunc,#1 
bl SetGpioFunction 
.unreq pinNum 
.unreq pinFunc 

的SetGpioFunction:

/* NEW 
* SetGpioFunction sets the function of the GPIO register addressed by r0 to the 
* low 3 bits of r1. 
* C++ Signature: void SetGpioFunction(u32 gpioRegister, u32 function) 
*/ 
.globl SetGpioFunction 
SetGpioFunction: 
    pinNum .req r0 
    pinFunc .req r1 
    cmp pinNum,#53 
    cmpls pinFunc,#7 
    movhi pc,lr 

    push {lr} 
    mov r2,pinNum 
    .unreq pinNum 
    pinNum .req r2 
    bl GetGpioAddress 
    gpioAddr .req r0 

    functionLoop$: 
     cmp pinNum,#9 
     subhi pinNum,#10 
     addhi gpioAddr,#4 
     bhi functionLoop$ 

    /* pinNum = 6 
     gpioAddr = 0x20200004 
    */ 

    add pinNum, pinNum,lsl #1 
    /* 
     pinNum = 18 (10010) 
    */ 
    lsl pinFunc,pinNum 
    /* 
     pinFunc = 1000000000000000000 
    */ 

    mask .req r3 
    mov mask,#7     /* r3 = 111 in binary */ 
    /* 
     mask = 111 
    */ 
    lsl mask,pinNum    /* r3 = 11100..00 where the 111 is in the same position as the function in r1 */ 
    /* 
     mask = 111000000000000000000 
    */ 
    .unreq pinNum 

    mvn mask,mask    /* r3 = 11..1100011..11 where the 000 is in the same poisiont as the function in r1 */ 
    /* 
     mask = 11..11000111111111111111111 
    */ 
    oldFunc .req r2 
    ldr oldFunc,[gpioAddr]  /* r2 = existing code */ 
    /* 
     oldFunc = 0x12 + (gpioaddr)0x20200004 = 0x20200016 
     oldFunc = 100000001000000000000000010110 
     mask = 111111111000111111111111111111 
    */ 
    and oldFunc,mask   /* r2 = existing code with bits for this pin all 0 */ 
    /* 
     oldFunc = 100000001000000000000000010110 
    */ 
    .unreq mask 

    /* 
     pinFunc = 000000000001000000000000000000 
     oldFunc = 100000001000000000000000010110 
    */ 
    orr pinFunc,oldFunc   /* r1 = existing code with correct bits set */ 
    /* 
     pinFunc = 100000001001000000000000010110 
     pinFunc = 0x20240016 
    */ 
    .unreq oldFunc 

    str pinFunc,[gpioAddr] 
    /* 
     Why do we add gpioaddr again? 
     pinFunc = 0x40440016 
    */ 
    .unreq pinFunc 
    .unreq gpioAddr 
    pop {pc} 

什麼我收到錯在這裏?先謝謝你。

回答

1
read the old setting for this register 
ldr oldFunc,[gpioAddr]  /* r2 = existing code */ 
mask off, zero out the bits we want to change, leaving the others unchanged 
and oldFunc,mask   /* r2 = existing code with bits for this pin all 0 */ 
or in the new bits we want to change the ones related to the pin in question 
orr pinFunc,oldFunc   /* r1 = existing code with correct bits set */ 
write the new value to the register so the changes for that pin function take effect 
str pinFunc,[gpioAddr] 

它是一個簡單的讀取 - 修改 - 寫入功能。

+0

謝謝,這讓我有點清醒 - 我只是假設我們正在寫入pinFunc的東西,而不是我們正在存儲pinFunc。 – Jan

+0

這是一個規則的例外,通常左邊的東西是右邊的目的地和東西的來源,但是對於一個商店來說,它是從左到右,而不是從右到左。 –