看head-common.s文件中的代码时候,有两段代码(代码见结尾,有省略),
一个实现了查询处理器类型的函数,一个实现了查询机器类型的函数。中间还有一段数据定义的代码。
这两个函数的第一条指令都是ADR指令,它是一个伪指令,汇编器会用其他指令(比如ADD)来实现这个指令的功能。
这个指令的格式和作用如下:
格式
ADR{cond}{.W} register,label
作用:将label的地址加载到register中。
不过这两个函数使用这个指令的方法,刚开始看的时候有点难理解。
__lookup_processor_type:
adr r3, 3f
__lookup_machine_type:
adr r3, 3b
乍看上去以为是价值3f和3b两个标签的地址呢,但在相关的代码和文件中根本查不到这两个标签。
实际上3f和3b是标签3后面加上了f和b属性。这个属性是gnu assembler as中定义的。[f] 的意思是forwords,[b] 的意思是backwords。目的是告诉汇编器加载当前代码前面的标签3的地址或者后面的标签3的地址(详细说明可以查看gnu as 手册)。
将这些知识和下面的定义联系起来,就会理解了,里面有标签3的定义。
.long __proc_info_begin
.long __proc_info_end
3: .long .
.long __arch_info_begin
.long __arch_info_end
代码:
__lookup_processor_type:
adr r3, 3f
ldmda r3, {r5 - r7}
sub r3, r3, r7 @ get offset between virt&phys
add r5, r5, r3 @ convert virt addresses to
add r6, r6, r3 @ physical address space
1: ldmia r5, {r3, r4} @ value, mask
and r4, r4, r9 @ mask wanted bits
teq r3, r4
beq 2f
add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
cmp r5, r6
blo 1b
mov r5, #0 @ unknown processor
2: mov pc, lr
。。。。
.long __proc_info_begin
.long __proc_info_end
3: .long .
.long __arch_info_begin
.long __arch_info_end
。。。。
__lookup_machine_type:
adr r3, 3b
ldmia r3, {r4, r5, r6}
sub r3, r3, r4 @ get offset between virt&phys
add r5, r5, r3 @ convert virt addresses to
add r6, r6, r3 @ physical address space
1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
teq r3, r1 @ matches loader number?
beq 2f @ found
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
cmp r5, r6
blo 1b
mov r5, #0 @ unknown machine
2: mov pc, lr
一个实现了查询处理器类型的函数,一个实现了查询机器类型的函数。中间还有一段数据定义的代码。
这两个函数的第一条指令都是ADR指令,它是一个伪指令,汇编器会用其他指令(比如ADD)来实现这个指令的功能。
这个指令的格式和作用如下:
格式
ADR{cond}{.W} register,label
作用:将label的地址加载到register中。
不过这两个函数使用这个指令的方法,刚开始看的时候有点难理解。
__lookup_processor_type:
adr r3, 3f
__lookup_machine_type:
adr r3, 3b
乍看上去以为是价值3f和3b两个标签的地址呢,但在相关的代码和文件中根本查不到这两个标签。
实际上3f和3b是标签3后面加上了f和b属性。这个属性是gnu assembler as中定义的。[f] 的意思是forwords,[b] 的意思是backwords。目的是告诉汇编器加载当前代码前面的标签3的地址或者后面的标签3的地址(详细说明可以查看gnu as 手册)。
将这些知识和下面的定义联系起来,就会理解了,里面有标签3的定义。
.long __proc_info_begin
.long __proc_info_end
3: .long .
.long __arch_info_begin
.long __arch_info_end
代码:
__lookup_processor_type:
adr r3, 3f
ldmda r3, {r5 - r7}
sub r3, r3, r7 @ get offset between virt&phys
add r5, r5, r3 @ convert virt addresses to
add r6, r6, r3 @ physical address space
1: ldmia r5, {r3, r4} @ value, mask
and r4, r4, r9 @ mask wanted bits
teq r3, r4
beq 2f
add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
cmp r5, r6
blo 1b
mov r5, #0 @ unknown processor
2: mov pc, lr
。。。。
.long __proc_info_begin
.long __proc_info_end
3: .long .
.long __arch_info_begin
.long __arch_info_end
。。。。
__lookup_machine_type:
adr r3, 3b
ldmia r3, {r4, r5, r6}
sub r3, r3, r4 @ get offset between virt&phys
add r5, r5, r3 @ convert virt addresses to
add r6, r6, r3 @ physical address space
1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
teq r3, r1 @ matches loader number?
beq 2f @ found
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
cmp r5, r6
blo 1b
mov r5, #0 @ unknown machine
2: mov pc, lr