【问题标题】:"Baking Pi: OK03" - Not understanding a function“烘焙 Pi:OK03” - 不了解函数
【发布时间】:2013-12-16 22:29:55
【问题描述】:

我对汇编语言完全陌生,刚买了一个树莓派。我知道我可以使用操作系统并开始使用 python 等进行编程,但我想更深入地了解一下。由于我的树莓派尚未到货,我无法测试 asm 代码。在第 OK03 课中,我查看了扩展解决方案 (download),我试图自己理解它,但我遇到了这个问题:为什么最后(再次)将 gpioAddr str'ed 到 pinFunc 上?我以 main.s 中的第一个调用为例来放置我的 cmets:

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}

我在这里做错了什么?提前谢谢你。

【问题讨论】:

    标签: assembly armv6


    【解决方案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]
    

    这是一个简单的读-修改-写函数。

    【讨论】:

    • 谢谢,这让我明白了一点——我只是假设我们正在向 pinFunc 写入一些东西,而不是我们正在存储 pinFunc。
    • 这是规则的一个例外,通常左边的东西是目的地,右边的东西是源,但对于商店来说,它是从左到右而不是从右到左.
    猜你喜欢
    • 1970-01-01
    • 2011-12-18
    • 2016-02-07
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    相关资源
    最近更新 更多