这个函数接收一个数组、要查找的左边界和右边界、以及要查找的目标元素。在函数中,我们首先通过 left 和 right 确定数组的中间元素 mid,并将其与目标元素进行比较。如果相等,则返回中间元素的索引。如果中间元素比目标元素小,则在右侧查找,反之在左侧查找。如果没有找到目标元素,则返回 -1 表示未找到。
具体来说,当执行 push {r4, lr} 指令时,该指令会将寄存器 r4 和 lr 中的值依次压入栈中,栈顶指针 SP 递减 8 个字节(因为 r4 和 lr 都是 4 字节长),指向新的栈顶地址。这样就实现了现场信息的保存,同时也为后续的代码执行做好了准备。
在需要恢复现场时,通常使用 pop 指令将栈中的数据弹出到寄存器中,恢复原来的值。具体来说,执行 pop {r4, lr} 指令时,该指令会将栈顶位置的值弹出到寄存器 lr 和 r4 中,栈顶指针 SP 递增 8 个字节,指向新的栈顶地址。这样就完成了现场信息的恢复,函数可以从保存现场的位置继续执行。
既然是通过汇编 push 指令来保持现场,为什么在该栈里面还可以使用 r4 呢?
在 ARM32 汇编语言中,使用 push 和 pop 指令可以方便地进行现场保存和恢复操作,这是因为这两个指令会自动将栈顶指针(Stack Pointer,SP)递减或递增,并将寄存器中的数据压入或弹出栈中。在调用函数时,通常会使用 push 指令将当前函数的返回地址和寄存器中的值压入栈中,然后使用 pop 指令在返回时将现场信息恢复到原来的状态。
由于 push 指令压栈时只保存了 r4 和 lr 寄存器的值,并没有在栈中分配空间来存储其他寄存器的值,因此在该函数的栈帧中并没有为其他寄存器(比如 r5 和 r6)分配空间。实际上,如果在该函数中需要使用这些寄存器,它们的值是可以直接保存在寄存器中的,不需要使用栈来保存。只有在需要保存到栈中的寄存器值,才需要通过 push 和 pop 指令来进行保存和恢复操作。
总之,通过使用 push 和 pop 指令来进行现场保存和恢复时,需要注意指令所保存的寄存器的数量和顺序,以及栈指针的位置等细节。
除了 push {r4, lr},在 ARM 汇编语言中还有其他类似的指令可以用于保存现场,以下是一些常见的指令: