From: http://www.cnblogs.com/logogcn/archive/2010/11/30/ARM_ B _BL.html
B or bl commands cause the processor to transfer to the subprogram name for execution. The difference between the two is that the BL command is transferred to the sub-
Before the program is executed, copy the address of the next instruction to R14 (LR, link register ). Because the BL command saves the location of the next command
Therefore, you can use the command "mov PC, LR" to return a subroutine. The B command cannot implement the return of subprograms, but can only implement
Simple jump. When programming, users can select appropriate subroutine call statements based on specific applications.
Area init, code, readonly
The pseudo command defines a code segment named init, and the attribute is read-only.
Entry; entry point ID of the program
.
.
BL delay; call Delay
.
.
MoV PC, LR; Return
As shown in the following blog, I think I copied it in details.
Summary of Arm Assembly commands
There are a lot of arm assembly instructions, but not a lot of commands are actually commonly used, and there are even fewer to be carefully considered.
What is useful is mov B Bl LDR Str
You can learn through the specific assembly code.
@ Disable Watch Dog Timer
MoV R1, #0x53000000 // immediate addressing mode
MoV R2, #0x0
STR R2, [R1]
The immediate number addressing method. The immediate number must be prefixed with "#". For hexadecimal numbers, you must add 0x or & after &. STR is
The most important command corresponds to LDR. The arm instruction set is load/storage-type, that is, it only processes
Data. STR and LDR are frequently used for access to system memory. STR transmits the data in the register to the specified address.
Memory. I personally think it is special:
STR (condition) Source register, <memory address>
For example, STR r0, [R1], which means R0-> [R1]. It writes the source register in front, which is opposite to mov and LDR.
LDR should be very common. LDR transfers data from memory to registers. And there is also a pseudo command LDR, so I have
This is a problem that cannot be solved. Read this Code:
MoV R1, # gpio_ctl_base
Add R1, R1, # ogpio_f
LDR R2, = 0x55aa // 0x55aa is an immediate number. What should I add?
I don't understand the LDR sentence. If you remove =, you cannot compile it. I checked some information, personal feeling
The cause is unknown: This = indicates that LDR is not an arm command, but a pseudo command. The LDR format is as follows:
LDR register, = numeric constant/label
It is used to call a 32-bit address or constant into a register. Too many, you may ask,
"Mov R2, # 0x55aa. This should be the case. However, LDR is a pseudo-command, that is, the compiler will process
It. What should I do? -- The rule is as follows: if the numeric constant is within the mov instruction range, the assembler uses this instruction as mov
. If it is not in the mov range, the assembler puts the constant behind the program and reads it using LDR. The offset between the PC and the constant cannot exceed
4 kb.
Then let's talk about the jump command. Arm has two jump methods.
(1) mov Pc <jump address> 〉
This type of Jump address is directly written to the PC of the program counter, which can jump freely in a 4 GB continuous space.
(2) B Bl blx BX can be used to redirect 32 MB forward or backward address space in the current command (why is it 32 MB?
Registers are 32-bit, and the value is the number of 24-Bit Signed characters, so 32 MB ).
B is the simplest jump command. Note that the actual value of the jump command is not an absolute address, but a relative address-relative to the current
An offset of the PC value, which is calculated by the assembler.
BL is very common. It saves the current content of the PC in the register LR (R14) before the jump. The classic usage of BL is as follows:
BL next; jump to next
......
Next
......
MoV PC, LR; returned from the subroutine.
Finally, I will mention the thumb command. The ARM architecture also supports 16-bit thumb instruction sets. The thumb instruction set is a subset of the arm instruction set.
While retaining the advantages of 32-bit code, it also greatly saves storage space. Because the thumb Instruction Set has only 16 characters in length
There are many. It and arm have their own application scenarios. 32-bit storage system and arm Instruction Set should be used for high system performance requirements;
16-bit storage systems and arm instruction sets should be used for high system costs and power consumption requirements.
Understanding of arm exceptions
Category: technical notes
Complete notes
1. Understanding of arm exceptions
There is a similar code in front of all the system boot programs, as shown below:
. Globl _ start; system reset position
_ Start: B reset; jump code corresponding to each exception Vector
Ldr pc, _ undefined_instruction; undefined command exception
Ldr pc, _ software_interrupt; software interruption exception
Ldr pc, _ prefetch_abort; Memory Operation exception
Ldr pc, _ data_abort; Data Exception
Ldr pc, _ not_used; not used
Ldr pc, _ IRQ; slow interruption exception
Ldr pc, _ Fiq; fast interruption exception
We can see that arm supports 7 types of exceptions. How does arm respond when an exception occurs? The first reset is abnormal.
Understand, it is placed at 0x0, and it is executed when it is powered on, and our program is always executed starting from resetting the exception handling program, because
This reset exception handler does not need to return. How can we execute the following exception handling functions?
After reading the book, I understood the abnormal response process of arm, so I was able to answer this question.
When an exception occurs, arm automatically performs the following steps:
(1) Place the address of the next instruction in the connection register LR (usually R14) so that the correct position can be obtained when an exception is returned.
Continue.
(2) copy the corresponding CPSR (current Program Status Register) to spsr (backup program status register. Exit from an exception
Then, the CPSR can be restored by the spsr.
(3) set the running mode bit of CPSR Based on the exception type.
(4) force the PC (program counter) to extract the next instruction from the relevant exception vector address and execute it to jump to the corresponding exception handling process
.
I did not go into detail about what these exception types represent. Because reset is usually concerned, and there is no need to figure it out.
Arm specifies the address of the exception vector:
B reset; reset 0x0
Ldr pc, _ undefined_instruction; undefined command exception 0x4
Ldr pc, _ software_interrupt; software interruption exception 0x8
Ldr pc, _ prefetch_abort; prefetch command 0xc
Ldr pc, _ data_abort; Data 0x10
Ldr pc, _ not_used; 0x14 is not used
Ldr pc, _ IRQ; slow interrupt exception 0x18
Ldr pc, _ Fiq; fast interrupt exception 0x1c
It is very easy to understand this code. When an exception occurs, the PC is forcibly set as the corresponding exception vector to jump to the corresponding
And then return to the main program for further execution.
The interrupt vectors of these boot programs are only used by the boot program itself. Once the boot program guides the Linux kernel, it will use
Your own interrupt vector.
Too many. This is another problem. For example, when arm is interrupted (IRQ), it always runs on 0x18. What about Linux kernel?
Can I use my own interrupt vectors? The reason is that the Linux kernel adopts page-based storage management. After MMU page ing is enabled
The sent address is a virtual address rather than a physical address. For Linux kernel, the virtual address 0x18 is mapped to the physical address
It is 0xc000 0018. Therefore, in Linux, put the interrupt vector at 0xc000 0018.
MMU has two main functions:
(1) Security: specifying access permissions
(2) provide address space: Convert discontinuous space into continuous space.
Is page-based storage implemented?
. Globl _ start; system reset position
_ Start: B reset; jump code corresponding to each exception Vector
Ldr pc, _ undefined_instruction; undefined command exception
......
_ Undefined_instruction:
. Word undefined_instruction
Some people may wonder why B reset is used in the first sentence;
Which of the following uses LDR?
To understand this problem, we take an undefined command exception as an example.
When this exception occurs, the CPU always jumps to 0x4. The address is a virtual address mapped to which physical address
Depends on the specific ing.
Ldr pc, _ undefined_instruction
Relative addressing: Jump to the label _ undefined_instruction. However, the real jump address is actually _ undefined_instruction.
-- Undefined_instruction. That. Word is equivalent:
_ Undefined_instruction DW undefined_instruction (for details, see note 3 ).
It is hard to say how far undefined_instruction is. It may be the same as the number _ undefined_instruction.
Page, maybe far away. However, except for reset, other exceptions may occur only after MMU starts to work.
The undefined_instruction address is also mapped to MMU.
When the power-on is started, the CPU starts to run from 0x0, and MMU has not started to work. At this time, the virtual address is the same as the physical address; the other side
After MMU starts to work, it may also happen. If the reset uses LDR, there will be problems, because the virtual address and physical
The address is completely different.
Therefore, the reason why reset uses B is that reset may occur before and after MMU is established, while other exceptions only occur when MMU is established.
. Use B reset, reset subprogram, and Reset vector on the same page, so there will be no problem (B is relatively redirected)
. If the two are too far apart, the compiler will report an error.