我对汇编语言完全陌生,只买了一个覆盆子pi。我知道我可以使用操作系统并开始使用python等进行编程,但我想深入了解一下。由于我的树莓派还没到,我无法测试asm代码。在课程OK03中,我查看了扩展解决方案(download),我试图自己理解它,但我遇到了这个问题:为什么gpioAddr最终会被调到pinFunc(再次)?我以main.s中的第一个调用为例发表了我的评论:
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}
我在这里弄错了什么?提前谢谢。
答案 0 :(得分: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]
这是一个简单的读 - 修改 - 写功能。