s3c2440裸机之中断向量的写法(二)

2022-12-07  

先说明一下LDR伪指令。

LDR伪指令将一个32位的常数或者一个地址值读取到寄存器中。

语法格式

LDR{cond} register,={expr|label-expr}

其中的符号及参数说明如下:

●cond为可选的指令执行条件。

●register为目标寄存器。

●expr为32位的常量,编译器将根据expr的取值情况,处理LDR伪指令如下。

●当expr表示的地址值没有超过MOV或MVN指令中地址的取值范围时,编译器使用合适的MOV或者MVN指令替代该LDR伪指令。

●当expr表示的地址超过了MOV或MVN指令中地址的取值范围时,编译器将该常数放在数据缓冲区中,同时用一条基于PC的LDR指令读取该常数。

●label-expr为基于PC的地址表达式或者是外部表达式。当label-expr为基于PC的地址表达式时,编译器将label-expr表示的数值放在数据缓冲区中,同时用一条基于PC的LDR指令读取该值。当label-expr为外部表达式,或者非当前段的表达式时,汇编编译器将在目标文件中插入链接重定位伪操作,这样链接器将在链接是生成该地址。


使用LDR伪操作编写中断向量表如下:

/* 中断向量表的第二种写法 */
ldr pc ,= reset
ldr pc ,= undefined_instruction
ldr pc ,= software_interrupt
ldr pc ,= prefetch_abort
ldr pc ,= data_abort
ldr pc ,= not_used
ldr pc ,= irq
ldr pc ,= fiq

reset:
	b reset
undefined_instruction:
	b undefined_instruction
software_interrupt:
	b software_interrupt
prefetch_abort:
	b prefetch_abort
data_abort:
	b data_abort
not_used:
	b not_used
irq:
	b irq
fiq:
	b fiq

反汇编结果如下:

33f80000 <.text>:
33f80000:	e59ff038 	ldr	pc, [pc, #56]	; 33f80040 <.text>
33f80004:	e59ff038 	ldr	pc, [pc, #56]	; 33f80044 <.text>
33f80008:	e59ff038 	ldr	pc, [pc, #56]	; 33f80048 <.text>
33f8000c:	e59ff038 	ldr	pc, [pc, #56]	; 33f8004c <.text>
33f80010:	e59ff038 	ldr	pc, [pc, #56]	; 33f80050 <.text>
33f80014:	e59ff038 	ldr	pc, [pc, #56]	; 33f80054 <.text>
33f80018:	e59ff038 	ldr	pc, [pc, #56]	; 33f80058 <.text>
33f8001c:	e59ff038 	ldr	pc, [pc, #56]	; 33f8005c <.text>
33f80020:	eafffffe 	b	33f80020 
33f80024:	eafffffe 	b	33f80024 
33f80028:	eafffffe 	b	33f80028 
33f8002c:	eafffffe 	b	33f8002c 
33f80030:	eafffffe 	b	33f80030 
33f80034:	eafffffe 	b	33f80034 
33f80038:	eafffffe 	b	33f80038 
33f8003c:	eafffffe 	b	33f8003c 
33f80040:	33f80020 	mvnccs	r0, #32	; 0x20
33f80044:	33f80024 	mvnccs	r0, #36	; 0x24
33f80048:	33f80028 	mvnccs	r0, #40	; 0x28
33f8004c:	33f8002c 	mvnccs	r0, #44	; 0x2c
33f80050:	33f80030 	mvnccs	r0, #48	; 0x30
33f80054:	33f80034 	mvnccs	r0, #52	; 0x34
33f80058:	33f80038 	mvnccs	r0, #56	; 0x38
33f8005c:	33f8003c 	mvnccs	r0, #60	; 0x3c

可以看出,LDR伪指令被编译器编译后,将地址常量存放在代码段的最后,并使用相对于PC偏移的地址进行访问。其中,地址常量为固定的0x33f80020...,也就是符号的地址在链接阶段已经确定了。


当代码运行于0地址时(重定位前),这条指令将使PC指向运行时地址,这时运行时地址还没有指令,所以会出错误。所以LDR register,=label-expr是地址相关的。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。