GNU ARM assembly .balignl alignment experiment

Publisher:星辰小鹿Latest update time:2016-04-20 Source: eefocusKeywords:GNU Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
The ".balignl 16 0xdeadbeef" statement appears in the start.s source file of u-boot. This statement is used to implement address alignment.

.balignl is similar to .align. The complete alignment statement format is: .align {alignment} {,fill} {,max}

alignment is used to specify the alignment mode. Possible values ​​are powers of 2. The default value is 4. fill is the filling content. By default, it is filled with 0. max is the maximum number of filling bytes. If the number of filling bytes exceeds max, no alignment is performed.

The following four situations are compared:

1. Normal situation

.word 0x12345678
.global _end_vect
_end_vect:
.balignl 16,0xdeadbeef

At this time, the address of .balignl is 0x50, which is exactly a multiple of 16, so it is not filled. As shown in the figure:

2. Fill in a word

//.word 0x12345678
.global _end_vect
_end_vect:
.balignl 16,0xdeadbeef

At this time, comment out 0x12345678. The address of .balignl is 0x4c, which is not a multiple of 16, so it needs to be filled with 0xdeadbeef. As shown in the figure:

3. Fill in three words

.word 0x12345678
.word 0x12345678
.global _end_vect
_end_vect:
.balignl 16,0xdeadbeef

At this time, add an extra 0x12345678, so that the address of .balignl is located at 0x54, which is not a multiple of 16, so it needs to be filled to 0x5f, and the content uses the specified 0xdeadbeef. As shown in the figure:

4. No filling if the limit is exceeded

.word 0x12345678
.word 0x12345678
.global _end_vect
_end_vect:
.balignl 16,0xdeadbeef,8

At this time, the maximum padding is limited to 8 bytes, but 12 bytes are required, so no padding is done. As shown in the figure:

 

Replenish:

UBOOT problem collection (1) --balignl 16, 0xdeadbeef
Sunday, March 27, 2011 at 12:57 PM

.balignl 16,0xdeadbeef

It is line 57 of the start.S file under the uboot startup file.

Because I was curious about the meaning of this code, I searched on Baidu:

====================================================

(http://haoyeren.blog.sohu.com/84511571.html)

First, we need to understand the meaning of .balignl. This is actually a pseudo-operator. The pseudo-operator means that there is no assembly instruction corresponding to it in the machine code, and it is the compiler that implements its function. .balignl is a variant of .balign. .balign means that starting from the current address, the address counter must end with an address that is an integer multiple of the first parameter, and a byte of information is recorded in front. The information content is the second parameter.

.balign 8, 0xde

It means that starting from the current address, fill a byte with 0xde in front of the address that is a multiple of 8. If the current address is exactly a multiple of 8, nothing is written to the memory.

=======================================================

http://blog.163.com/mcu_expert/blog/static/131245153201073125947792/

Regarding the sentence .balignl 16,0xdeadbeef, the function description is correct, it just wants to insert the special memory value 0xdeadbeef at a certain position. The mistake is in my understanding of the 16. 16 is 16 bytes, which is correct, but the origin of this 16 is not what I understand as at least 16 bytes to ensure the insertion of this special memory value under any circumstances. In the message of this blog, I answered a question from a netizen and gave an example that when the pc is 0x00000007 address and the offset is 8 bytes, there is not enough content for 4 bytes at this time. The deduction from this that at least 16 bytes are required to ensure the insertion of this special memory value is also completely wrong.

Let me give you a counter-example. If we follow the explanation given to that netizen, even if there is a 16-byte offset, if the pc address is 0x0000000F, there is only space for one character, so the deadbeef value is still not enough. By analogy, even if this value is any value, according to the wrong logic I explained before, there are still cases where it is not satisfied, haha. So my previous inference was wrong, and I would like to correct it. I will now explain the origin of the value 16.

The ARM920T processor core supports two instruction lengths: 32-bit and 16-bit. The 16-bit instruction is called the thumb instruction set. Since I am using the 32-bit instruction set, everything is described in terms of the 32-bit instruction set.

Since it is a 32-bit instruction set, one instruction occupies 32 bits, or 4 bytes. Therefore, in the debugger, the address display also jumps by 4 bytes (there is a link to the screenshot of the debugger in the comments of this blog post), so the value of pc also jumps by 4 bytes. There is no possibility that the value of pc is 0x00000007, haha.

This place fills in 16 offsets because

.globl _start // does not occupy memory
_start: b start_code // occupies 4 bytes of memory
ldr pc, _undefined_instruction // occupies 4 bytes of memory
ldr pc, _software_interrupt // occupies 4 bytes of memory
ldr pc, _prefetch_abort // occupies 4 bytes of memory
ldr pc, _data_abort // occupies 4 bytes of memory
ldr pc, _not_used // occupies 4 bytes of memory
ldr pc, _irq // occupies 4 bytes of memory
ldr pc, _fiq // occupies 4 bytes of memory

It takes up 4x8=32 bytes of memory.

_undefined_instruction: .word undefined_instruction //Occupies 4 bytes of memory_software_interrupt
: .word software_interrupt //Occupies 4 bytes of
memory_prefetch_abort: .word prefetch_abort //Occupies 4 bytes of memory_data_abort
: .word data_abort //Occupies 4 bytes of memory_not_used
: .word not_used //Occupies 4 bytes of memory_irq
: .word irq //Occupies 4 bytes of memory_fiq
: .word fiq //Occupies 4 bytes of memory

It takes up 4x7=28 bytes of memory.

So before this .balignl 16,0xdeadbeef instruction, a total of 4x15=60 bytes of memory were occupied, so the author of this code simply added 1 to the number 15, that is, 16, moved the current pointer back to address 64, and then inserted the special value 0xdeadbeef in front.

I don't know if this is a mistake by the author, or a lucky coincidence, or what, in fact, there are many cases for this offset value. If it is the smallest value, then it can also be written as .balignl 8,0xdeadbeef, which can also achieve the same purpose. Because 60 is not a multiple of 8, but 64 is a multiple of 8 (60 to 64 are not multiples of 8, nor are they multiples of 16, so writing 8 and 16 are both feasible), if you write 8, it will be inserted just in front of 64, that is, the memory start address 60. If it is a little bigger, then filling 32 can also achieve the same effect, that is, .balignl 32,0xdeadbeef, the reason is the same as above. Of course, it cannot be 4, because the pc value is always a multiple of 4 (60 is a multiple of 4) at any time, as long as it is not 0, it is a multiple of 4, haha, this value is not acceptable, if this value is used, 0xdeadbeef will never be inserted, haha.


Keywords:GNU Reference address:GNU ARM assembly .balignl alignment experiment

Previous article:How does the S3C2440 clock work?
Next article:ARM standard assembly and GNU assembly

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号