There are 7 operating states for ARM, and the stack pointer Register (SP) for each state is independent. So, for each processor pattern that needs to be used in the program, define a stack address for the SP. The process is to modify the status bits within the status register, so that the processor switches to the desired mode, and assigns a value to the SP. It is important to note that you do not switch to user mode for the stack setting in this mode, because you can no longer manipulate CPSR to return to other modes after entering user mode.
Define the value of the CPSR register m[4:0] for each mode, which determines which mode to enter and refer to the relevant data sheet.
MODE_USR EQU 0x10
Mode_fiq EQU 0x11
MODE_IRQ EQU 0x12
Mode_svc EQU 0x13
Mode_abt EQU 0x17
Mode_und EQU 0x1B
Mode_sys EQU 0x1F
I_bit EQU 0x80; When I bit was set (1), IRQ is disabled
F_bit EQU 0x40; When F bit was set (1), FIQ is disabled
Here is the code snippet that initializes the stack:
Initstack
MOV R0, LR
; /* Set the management mode stack */
MSR Cpsr_c, # (Mode_svc | I_bit | F_bit); 0xd3
LDR SP, Stacksvc
; /* Set break mode stack */
MSR Cpsr_c, # (MODE_IRQ | I_bit | F_bit); 0xd2
LDR SP, STACKIRQ
; /* Set fast interrupt mode stack */
MSR Cpsr_c, # (Mode_fiq | I_bit | F_bit); 0xd1
LDR SP, Stackfiq
; /* Set Abort mode stack */
MSR Cpsr_c, # (Mode_abt | I_bit | F_bit); 0xd7
LDR SP, Stackabt
; /* Set undefined schema stack */
MSR Cpsr_c, # (Mode_und | I_bit | F_bit); 0xdb
LDR SP, Stackund
; /* Set the system mode stack */
MSR Cpsr_c, # (Mode_sys | I_bit | F_bit); 0xDF
LDR SP, STACKUSR
MOV PC, R0
STACKUSR DCD Usrstackspace + (usr_stack_legth-1) * 4
Stacksvc DCD Svcstackspace + (svc_stack_legth-1) * 4
STACKIRQ DCD Irqstackspace + (irq_stack_legth-1) * 4
Stackfiq DCD Fiqstackspace + (fiq_stack_legth-1) * 4
Stackabt DCD Abtstackspace + (abt_stack_legth-1) * 4
Stackund DCD Undtstackspace + (und_stack_legth-1) * 4
; /* Allocate stack space */
Area mystacks, DATA, Noinit, align=2
Usrstackspace Space Usr_stack_legth * 4; User (System) mode stack spaces
Svcstackspace Space Svc_stack_legth * 4; management mode stack spaces
Irqstackspace Space Irq_stack_legth * 4; break mode stack spaces
Fiqstackspace Space Fiq_stack_legth * 4; quick break mode stack space
Abtstackspace Space Abt_stack_legth * 4; abort semantic mode stack spaces
Undtstackspace SPACE und_stack_legth * 4; no schema stack defined
Take the management mode stack space as an example to illustrate.
Svc_stack_legth is defined as 16, with the result of allocating 16 4-byte storage space, initializing the storage space to 0, and pointing the SP at the bottom of the stack (memory high).
From the above memory content can be seen above. The management mode stack has been allocated from 0x00008080~0x00008044 altogether 16*4 byte space. Where the 0x00008040 address memory is placed on the 0x00008080, which is the value of the pointer at the bottom of the stack.
That is, stacksvc DCD Svcstackspace + (svc_stack_legth-1) * 4 This 32-bit pseudo-instruction, after compiling, is placed on the 0x00008040 (stacksvc) address svcstacks Pace Address Value (0x00008080). That is, the 0x00008080 was assigned to SP.
Then look at the address 0x00008080~0x00008044 on the content, all is Andeq r0,r0,r0. Translated from the assembly instruction format, Andeq r0,r0,r0 was translated into 16 block code, just as 0x00000000.
Stack initialization parsing in startup code magicchip posted on 2007-7-23 20:10:00
2
Recommended
If you support this site, please click on this site ads, to express support for me.
In the startup code are:
; Define the size of the stack
Svc_stack_legth EQU 0
Fiq_stack_legth EQU 0
Irq_stack_legth EQU 128
Abt_stack_legth EQU 0
Und_stack_legth EQU 0
Reset
LDR PC, Resetaddr
LDR PC, Undefinedaddr
LDR PC, Swi_addr
LDR PC, Prefetchaddr
LDR PC, Dataabortaddr
DCD 0xb9205f80
LDR pc, [pc, #-0xff0]
LDR PC, Fiq_addr
Resetaddr DCD Resetinit
Undefinedaddr DCD Undefined
Swi_addr DCD Softwareinterrupt
Prefetchaddr DCD Prefetchabort
Dataabortaddr DCD Dataabort
Nouse DCD 0
IRQ_ADDR DCD 0
Fiq_addr DCD Fiq_handler
; Directives not defined
Undefined
B Undefined
; Soft Interrupt
Softwareinterrupt
B Softwareinterrupt
Take command abort.
Prefetchabort
B Prefetchabort
Take data to abort
Dataabort
B Dataabort
; rapid interruption
Fiq_handler
B Fiq_handler
Stacksvc DCD Svcstackspace + (svc_stack_legth-1) * 4
STACKIRQ DCD Irqstackspace + (irq_stack_legth-1) * 4
Stackfiq DCD Fiqstackspace + (fiq_stack_legth-1) * 4
Stackabt DCD Abtstackspace + (abt_stack_legth-1) * 4
Stackund DCD Undtstackspace + (und_stack_legth-1) * 4
;/* Allocate stack space */
Area mystacks, DATA, Noinit, align=2
Svcstackspace Space Svc_stack_legth * 4; management mode stack spaces
Irqstackspace Space Irq_stack_legth * 4; break mode stack spaces
Fiqstackspace Space Fiq_stack_legth * 4; quick break mode stack space
Abtstackspace Space Abt_stack_legth * 4; abort semantic mode stack spaces
Undtstackspace SPACE und_stack_legth * 4; no schema stack defined
Among them, Irq_stack_legth is 128, according to
Irqstackspace Space Irq_stack_legth * 4; break mode stack spaces
Irqstackspace is the first address of a 128*4 byte space, and then the
STACKIRQ DCD Irqstackspace + (irq_stack_legth-1) * 4
, Irqstackspace + (irq_stack_legth-1) * 4 = 128*4 + (128-1) = (128+127), meaning the actual IRQ stack size is (128+127) * 4 bytes, is this true.
Answer 1: Is that so? STACKIRQ DCD Irqstackspace + (irq_stack_legth-1) * 4
The irqstackspace in the 128*4 is the first address of a contiguous byte, Irqstackspace + (irq_stack_legth-1) * 4 represents the offset of a base and a memory size, thus constituting 128*4 contiguous byte space.
Answer 2: But if that's the case, write it directly as
Stackirq DCD (irq_stack_legth) * 4
No, it's OK. Why do you use space statements?
Answer 3: Not as you say STACKIRQ DCD Irqstackspace + (irq_stack_legth-1) * 4
Here the STACKIRQ is written by Shelf, is a label, the essence is an address. The pseudo-directive is to place a value (Irqstackspace + (irq_stack_legth-1) * 4) on an address (STACKIRQ).
Irqstackspace SPACE Irq_stack_legth * 4
Is the space that is assigned a certain length (Irq_stack_legth * 4) starting from the location (address) of the irqstackspace.
The STACKIRQ actually points to the stack's top (the highest address of the stack).
Please refer to the common arm instruction set and compilation written by Wancheng, which contains explanations of these two instructions.
Answer 4:eyuge2 's right, Eyuge2 's right, Stakckirq. The stack top address of the vector interrupt stack
Answer 5:re I know where the problem is, I didn't understand the use of DCD and space properly.
It was wrong to follow the first post on my roof, and it was inappropriate to think so, because then there would be
(128+127) bytes as the stack space.
And in the third post that is sent later:
Is that so?
STACKIRQ DCD Irqstackspace + (irq_stack_legth-1) * 4
The irqstackspace in the 128*4 is the first address of a contiguous byte, Irqstackspace + (irq_stack_legth-1) * 4 represents a base add
The offset of the previous memory size makes up the 128*4 contiguous byte space.
is correct, but it confuses the functions of the DCD directive and the Space Command.
<label> DCD expr1 {, EXPR2}{,EXPR3} ...
The value of the expression is stored in the current address, this address is labeled as label, just EXPR1,EXPR2,EXPR3 ... Value is loaded in the label
At the beginning of the address, it is not possible to allocate expr1 consecutive bytes;
And space is used in the format
{Label} SPACE Expr
This command is the true allocation of expr a contiguous byte, and the first address of these contiguous bytes is a label,
So
In
STACKIRQ DCD Irqstackspace + (irq_stack_legth-1) * 4
, Irstackspace can be thought of as a base address, (IRQ_STACK_LEGTH-1) * 4 as an offset, both the and is the address of the most
High-end, this highest address is the stack STACKIRQ top. And the result of Irqstackspace + (irq_stack_legth-1) * 4 is after all a
Value, the value is stored in a DCD pseudo-instruction in the memory address labeled STACKIRQ, which reads the top of the stack when the STACKIRQ is accessed.
's address.
Just looked at the eyuge2 and autumn Maple Leaf replies to think so understanding should be, thank you two, thank you.
Answer 6: Yes, that's how you understand it!