Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
829 views
in Technique[技术] by (71.8m points)

assembly - Why should code be aligned to even-address boundaries on x86?

I am working through Kip Irvine's "Assembly Language for x86 Processors, sixth edition" and am really enjoying it.

I have just read about the NOP mnemonic in the following paragraph:

"It [NOP] is sometimes used by compilers and assemblers to align code to 
 even-address boundaries."

The example given is:

00000000   66 8B C3   mov ax, bx
00000003   90         nop
00000004   8B D1      mov edx, ecx

The book then states:

"x86 processors are designed to load code and data more quickly from even 
 doubleword addresses."

My question is: Is the reason this is so is because for the x86 processors the book refers to (32 bit), the word size of the CPU is 32 bits and therefore it can pull the instructions with the NOP in and process them in one go ? If this is the case, I am assuming that a 64 bit processor with a word size of a quadword would do this with a hypothetical 5 bytes of code plus a nop ?

Lastly, after I write my code, should I go through and correct alignment with NOP's to optimize it, or will the compiler (MASM, in my case), do this for me, as the text seems to imply ?

Thanks,

Scott

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Code that's executed on word (for 8086) or DWORD (80386 and later) boundaries executes faster because the processor fetches whole (D)words. So if your instructions aren't aligned then there is a stall when loading.

However, you can't dword-align every instruction. Well, I guess you could, but then you'd be wasting space and the processor would have to execute the NOP instructions, which would kill any performance benefit of aligning the instructions.

In practice, aligning code on dword (or whatever) boundaries only helps when the instruction is the target of a branching instruction, and compilers typically will align the first instruction of a function, but won't align branch targets that can also be reached by fall through. For example:

MyFunction:
    cmp ax, bx
    jnz NotEqual
    ; ... some code here
NotEqual:
    ; ... more stuff here

A compiler that generates this code will typically align MyFunction because it is a branch target (reached by call), but it won't align the NotEqual because doing so would insert NOP instructions that would have to be executed when falling through. That increases code size and makes the fall-through case slower.

I would suggest that if you're just learning assembly language, that you don't worry about things like this that will most often give you marginal performance gains. Just write your code to make things work. After they work, you can profile them and, if you think it's necessary after looking at the profile data, align your functions.

The assembler typically won't do it for you automatically.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...