mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-04-28 19:54:01 +00:00
This patch creates initial draft of Assembly coding guidelines. Signed-off-by: Shiqing Gao <shiqing.gao@intel.com>
793 lines
19 KiB
ReStructuredText
793 lines
19 KiB
ReStructuredText
.. _asm_coding_guidelines:
|
|
|
|
Assembly Language Coding Guidelines
|
|
###################################
|
|
|
|
.. contents::
|
|
:local:
|
|
|
|
|
|
General
|
|
*******
|
|
|
|
ASM-GN-01: One address shall not be declared by two labels
|
|
==========================================================
|
|
|
|
Compliant example::
|
|
|
|
asm_showcase_1:
|
|
movl $0x1, %eax
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_showcase_1:
|
|
asm_showcase_2:
|
|
movl $0x1, %eax
|
|
|
|
|
|
ASM-GN-02: Names reserved for use by the assembler shall not be used for any other purpose
|
|
==========================================================================================
|
|
|
|
Names defined by developers shall not be the same as an assembler directive,
|
|
instruction prefix, instruction mnemonic, or register name.
|
|
|
|
Compliant example::
|
|
|
|
asm_showcase_1:
|
|
movl $0x1, %eax
|
|
|
|
asm_showcase_2:
|
|
movl $0x2, %eax
|
|
|
|
asm_showcase_3:
|
|
movl $0x3, %eax
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
text:
|
|
movl $0x1, %eax
|
|
|
|
mov:
|
|
movl $0x2, %eax
|
|
|
|
eax:
|
|
movl $0x3, %eax
|
|
|
|
|
|
ASM-GN-03: All declared labels shall be used
|
|
============================================
|
|
|
|
Otherwise, the label shall be removed.
|
|
|
|
Compliant example::
|
|
|
|
asm_showcase_1:
|
|
movl $0x1, %eax
|
|
jmp asm_showcase_2
|
|
|
|
/* do something */
|
|
|
|
asm_showcase_2:
|
|
movl $0x2, %eax
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_showcase_1:
|
|
movl $0x1, %eax
|
|
|
|
/*
|
|
* 'asm_showcase_2' is not used anywhere, including
|
|
* all C source/header files and Assembly files.
|
|
*/
|
|
asm_showcase_2:
|
|
movl $0x2, %eax
|
|
|
|
|
|
ASM-GN-04: Magic numbers shall be used with restrictions
|
|
========================================================
|
|
|
|
Only the following cases shall be allowed:
|
|
|
|
a) The magic number is defined as a MACRO with a name clearly indicating its
|
|
meaning.
|
|
b) The meaning of the magic number is clearly documented in the comments before
|
|
its usage.
|
|
c) The meaning of the magic number is straightforward in the specific context.
|
|
|
|
Compliant example::
|
|
|
|
.section .data
|
|
showcase_data:
|
|
/* 0xff000000 means <something> */
|
|
.long 0xff000000
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
.section .data
|
|
showcase_data:
|
|
.long 0xff000000
|
|
|
|
|
|
ASM-GN-05: Parentheses shall be used to set the operator precedence explicitly
|
|
==============================================================================
|
|
|
|
Compliant example::
|
|
|
|
.section .data
|
|
showcase_data:
|
|
/* 0x1234 means <something> */
|
|
.long 0x1234 * (0x1234 >> 2)
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
.section .data
|
|
showcase_data:
|
|
/* 0x1234 means <something> */
|
|
.long 0x1234 * 0x1234 >> 2
|
|
|
|
|
|
ASM-GN-06: .end directive statement shall be the last statement in an Assembly file
|
|
===================================================================================
|
|
|
|
This rule only applies to the Assembly file which uses .end directive. .end
|
|
directive shall be the last statement in this case. All the statements past .end
|
|
directive will not be processed by the assembler.
|
|
|
|
Compliant example::
|
|
|
|
#include <types.h>
|
|
#include <spinlock.h>
|
|
|
|
.macro asm_showcase_mov
|
|
movl $0x1, %eax
|
|
.endm
|
|
|
|
.end
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
#include <types.h>
|
|
|
|
.end
|
|
|
|
#include <spinlock.h>
|
|
|
|
.macro asm_showcase_mov
|
|
movl $0x1, %eax
|
|
.endm
|
|
|
|
|
|
ASM-GN-07: Infinite loop shall not exist
|
|
========================================
|
|
|
|
Compliant example::
|
|
|
|
asm_showcase_1:
|
|
movl $0x1, %eax
|
|
jmp asm_showcase_2
|
|
|
|
/* do something */
|
|
|
|
asm_showcase_2:
|
|
movl $0x2, %eax
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_showcase_1:
|
|
movl $0x1, %eax
|
|
jmp asm_showcase_1
|
|
|
|
|
|
ASM-GN-08: All code shall be reachable
|
|
======================================
|
|
|
|
Compliant example::
|
|
|
|
asm_showcase:
|
|
movl %ebx, %eax
|
|
test $0x400, %eax
|
|
jne asm_test
|
|
movl $0x2, %eax
|
|
movl $0x3, %eax
|
|
|
|
asm_test:
|
|
movl $0x6, %eax
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_showcase:
|
|
movl %ebx, %eax
|
|
jmp asm_test
|
|
/* the following two lines have no chance to be executed */
|
|
movl $0x2, %eax
|
|
movl $0x3, %eax
|
|
|
|
asm_test:
|
|
movl $0x6, %eax
|
|
|
|
|
|
ASM-GN-09: Far jump shall be used with restrictions
|
|
===================================================
|
|
|
|
Jumping to an instruction located in a different segment shall only be used for
|
|
the following two cases:
|
|
|
|
a) Code bit changes, such as change from 32-bit mode to 64-bit mode.
|
|
b) System resumes from S3. In this case, Global Descriptor Table (GDT) is set by
|
|
Bootloader/BIOS and far jump has to be used to correct the Code Segment (CS).
|
|
|
|
Compliant example::
|
|
|
|
.code32
|
|
execution_32:
|
|
/*
|
|
* do something in 32-bit mode,
|
|
* then,
|
|
* perform a far jump to start executing in 64-bit mode
|
|
*/
|
|
ljmp $0x0008, $execution_64_2
|
|
|
|
.code64
|
|
execution_64_1:
|
|
/* do something in 64-bit mode */
|
|
|
|
execution_64_2:
|
|
/* do something in 64-bit mode */
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
.data
|
|
asm_showcase_data:
|
|
.word 0x0008
|
|
|
|
.code32
|
|
execution_32:
|
|
/* do something in 32-bit mode */
|
|
ljmp $0x0008, $asm_showcase_data
|
|
|
|
|
|
ASM-GN-10: Assembler directives shall be used with restrictions
|
|
===============================================================
|
|
|
|
Usage of the assembler directive refers to GNU assembler 'as' user manual. Only
|
|
the following assembler directives may be used:
|
|
|
|
1) .align
|
|
2) .end
|
|
3) .extern
|
|
4) repeat related directives, including .rept and .endr
|
|
5) global related directives, including .global and .globl
|
|
6) macro related directives, including .altmacro, .macro, and .endm
|
|
7) code bit related directives, including .code16, .code32, and .code64
|
|
8) section related directives, including .section, .data, and .text
|
|
9) number emission related directives, including .byte, .word, .short, .long,
|
|
and .quad
|
|
10) .org, which shall be used with restrictions. It shall only be used to
|
|
advance the location counter due to code bit changes, such as change from 32-bit
|
|
mode to 64-bit mode.
|
|
|
|
|
|
|
|
Functions
|
|
*********
|
|
|
|
ASM-FN-01: Function shall have return statement
|
|
===============================================
|
|
|
|
Compliant example::
|
|
|
|
asm_func_showcase:
|
|
movl $0x2, %eax
|
|
ret
|
|
|
|
asm_showcase:
|
|
movl $0x1, %eax
|
|
call asm_func_showcase
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_func_showcase:
|
|
movl $0x2, %eax
|
|
|
|
asm_showcase:
|
|
movl $0x1, %eax
|
|
call asm_func_showcase
|
|
|
|
|
|
ASM-FN-02: A function shall only have one entry point
|
|
=====================================================
|
|
|
|
The label in a function shall only be used inside. Jumping into the function
|
|
from outside via this label shall not be allowed. This rule applies to both
|
|
conditional jump and unconditional jump.
|
|
|
|
Compliant example::
|
|
|
|
asm_func_showcase:
|
|
test $0x400, %eax
|
|
jne tmp
|
|
movl $0x1, %eax
|
|
tmp:
|
|
movl $0x2, %eax
|
|
ret
|
|
|
|
asm_showcase:
|
|
movl $0x1, %eax
|
|
call asm_func_showcase
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_func_showcase:
|
|
movl $0x1, %eax
|
|
tmp:
|
|
movl $0x2, %eax
|
|
ret
|
|
|
|
asm_showcase:
|
|
movl $0x1, %eax
|
|
call asm_func_showcase
|
|
jmp tmp
|
|
|
|
|
|
ASM-FN-03: A function shall only have one return statement
|
|
==========================================================
|
|
|
|
Compliant example::
|
|
|
|
asm_func_showcase:
|
|
test $0x400, %eax
|
|
jne tmp
|
|
movl $0x2, %eax
|
|
jmp showcase_return
|
|
tmp:
|
|
movl $0x3, %eax
|
|
showcase_return:
|
|
ret
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_func_showcase:
|
|
test $0x400, %eax
|
|
jne tmp
|
|
movl $0x2, %eax
|
|
ret
|
|
tmp:
|
|
movl $0x3, %eax
|
|
ret
|
|
|
|
|
|
ASM-FN-04: Function shall only be entered by explicit call
|
|
==========================================================
|
|
|
|
Falling through from prior instruction shall not be allowed.
|
|
|
|
Compliant example::
|
|
|
|
asm_func_showcase:
|
|
movl $0x2, %eax
|
|
ret
|
|
|
|
asm_showcase:
|
|
movl $0x1, %eax
|
|
call asm_func_showcase
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_showcase:
|
|
movl $0x1, %eax
|
|
|
|
asm_func_showcase:
|
|
movl $0x2, %eax
|
|
ret
|
|
|
|
|
|
ASM-FN-05: A jump instruction shall not be used to jump out of a function
|
|
=========================================================================
|
|
|
|
This rule applies to both conditional jump and unconditional jump.
|
|
|
|
Compliant example::
|
|
|
|
asm_func_showcase:
|
|
movl $0x2, %eax
|
|
ret
|
|
|
|
asm_showcase:
|
|
movl $0x1, %eax
|
|
call asm_func_showcase
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_func_showcase:
|
|
movl $0x2, %eax
|
|
jmp asm_test
|
|
ret
|
|
|
|
asm_showcase:
|
|
movl $0x1, %ebx
|
|
call asm_func_showcase
|
|
|
|
asm_test:
|
|
cli
|
|
|
|
|
|
ASM-FN-06: Recursion shall not be used in function calls
|
|
========================================================
|
|
|
|
Compliant example::
|
|
|
|
asm_func_showcase:
|
|
movl $0x2, %eax
|
|
ret
|
|
|
|
asm_showcase:
|
|
movl $0x1, %eax
|
|
call asm_func_showcase
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_func_showcase:
|
|
movl $0x2, %eax
|
|
call asm_func_showcase
|
|
ret
|
|
|
|
asm_showcase:
|
|
movl $0x1, %eax
|
|
call asm_func_showcase
|
|
|
|
|
|
ASM-FN-07: Cyclomatic complexity shall be less than 10
|
|
======================================================
|
|
|
|
A function with cyclomatic complexity greater than 10 shall be split into
|
|
multiple sub-functions to simplify the function logic.
|
|
|
|
Compliant example::
|
|
|
|
asm_func_showcase:
|
|
/* do something */
|
|
cmpl $0x0, %eax
|
|
je tmp
|
|
cmpl $0x1, %eax
|
|
je tmp
|
|
cmpl $0x2, %eax
|
|
je tmp
|
|
/* do something */
|
|
tmp:
|
|
/* do something */
|
|
ret
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_func_showcase:
|
|
/* do something */
|
|
cmpl $0x0, %eax
|
|
je tmp
|
|
cmpl $0x1, %eax
|
|
je tmp
|
|
cmpl $0x2, %eax
|
|
je tmp
|
|
cmpl $0x3, %eax
|
|
je tmp
|
|
cmpl $0x4, %eax
|
|
je tmp
|
|
cmpl $0x5, %eax
|
|
je tmp
|
|
cmpl $0x6, %eax
|
|
je tmp
|
|
cmpl $0x7, %eax
|
|
je tmp
|
|
cmpl $0x8, %eax
|
|
je tmp
|
|
cmpl $0x9, %eax
|
|
je tmp
|
|
cmpl $0xa, %eax
|
|
je tmp
|
|
cmpl $0xb, %eax
|
|
je tmp
|
|
cmpl $0xc, %eax
|
|
je tmp
|
|
cmpl $0xd, %eax
|
|
je tmp
|
|
cmpl $0xe, %eax
|
|
je tmp
|
|
/* do something */
|
|
tmp:
|
|
/* do something */
|
|
ret
|
|
|
|
|
|
|
|
Coding Style
|
|
************
|
|
|
|
ASM-CS-01: One instruction statement shall not be split into multiple lines
|
|
===========================================================================
|
|
|
|
Compliant example::
|
|
|
|
movl $0x2, %eax
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
movl $0x2, \
|
|
%eax
|
|
|
|
|
|
ASM-CS-02: Assembler directive statements shall be aligned
|
|
==========================================================
|
|
|
|
An assembler directive statement is composed of directive and arguments.
|
|
Arguments are optional depending on the use case.
|
|
Some detailed rules about the alignment are listed below:
|
|
|
|
a) Assembler directives shall be aligned with one tab if the statement is in the
|
|
code block under any label from functional perspective. Otherwise, assembler
|
|
directives shall be aligned to the start of the line.
|
|
b) Tabs shall be used to separate the directive and the first argument, where
|
|
applicable. The number of tabs could be decided by the developers based on each
|
|
case and it shall guarantee that the first argument is aligned in each directive
|
|
block.
|
|
c) A single space shall be used to separate multiple arguments.
|
|
|
|
Compliant example::
|
|
|
|
.extern cpu_primary_save32
|
|
.extern cpu_primary_save64
|
|
|
|
.section multiboot_header, "a"
|
|
.align 4
|
|
.long 0x0008
|
|
.long 0x0018
|
|
|
|
.section entry, "ax"
|
|
.align 8
|
|
.code32
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
.extern cpu_primary_save32
|
|
.extern cpu_primary_save64
|
|
|
|
.section multiboot_header, "a"
|
|
.align 4
|
|
.long 0x0008
|
|
.long 0x0018
|
|
|
|
.section entry, "ax"
|
|
.align 8
|
|
.code32
|
|
|
|
|
|
ASM-CS-03: Labels shall be aligned to the start of the line
|
|
===========================================================
|
|
|
|
Compliant example::
|
|
|
|
asm_showcase_1:
|
|
movl $0x1, %eax
|
|
|
|
asm_showcase_2:
|
|
movl $0x2, %eax
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_showcase_1:
|
|
movl $0x1, %eax
|
|
|
|
asm_showcase_2:
|
|
movl $0x2, %eax
|
|
|
|
|
|
ASM-CS-04: Instruction statements shall be aligned
|
|
==================================================
|
|
|
|
An instruction statement is composed of instruction prefix, instruction
|
|
mnemonic, and instruction operands. Instruction prefix and instruction operands
|
|
are optional depending on the use case.
|
|
Some detailed rules about the alignment are listed below:
|
|
|
|
a) The start of instruction statements shall be aligned with one tab if the
|
|
instruction statement is in the code block under any label from functional
|
|
perspective. Otherwise, the start of instruction statements shall be aligned to
|
|
the start of the line. The start of the instruction could either be the
|
|
instruction mnemonic or the instruction prefix.
|
|
b) One space shall be used to separate the instruction prefix and the
|
|
instruction mnemonic, where applicable.
|
|
c) Tabs shall be used to separate the instruction mnemonic and the first
|
|
instruction operand, where applicable. The number of tabs could be decided by
|
|
the developers based on each case and it shall guarantee that the first
|
|
instruction operand in the code block under one label is aligned.
|
|
d) A single space shall be used to separate multiple operands.
|
|
|
|
Compliant example::
|
|
|
|
asm_showcase_1:
|
|
movl $0x1, %eax
|
|
lock and %rcx, (%rdx)
|
|
|
|
asm_showcase_2:
|
|
movl $0x3, %eax
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_showcase_1:
|
|
movl $0x1, %eax
|
|
lock and %rcx, (%rdx)
|
|
|
|
asm_showcase_2:
|
|
movl $0x2, %eax
|
|
|
|
|
|
ASM-CS-05: '//' shall not be used for comments
|
|
===============================================
|
|
|
|
'/* \*/' shall be used to replace '//' for comments.
|
|
|
|
Compliant example::
|
|
|
|
/* This is a comment */
|
|
movl $0x1, %eax
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
// This is a comment
|
|
movl $0x1, %eax
|
|
|
|
|
|
ASM-CS-06: Tabs shall be 8 characters wide
|
|
==========================================
|
|
|
|
A tab character shall be considered 8-character wide when limiting the line
|
|
width.
|
|
|
|
|
|
ASM-CS-07: Each line shall contain at most 120 characters
|
|
=========================================================
|
|
|
|
No more than 120 characters shall be on a line, with tab stops every 8
|
|
characters.
|
|
|
|
Compliant example::
|
|
|
|
/*
|
|
* This is a comment. This is a comment. This is a comment. This is a comment.
|
|
* This is a comment. This is a comment. This is a comment.
|
|
*/
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
/* This is a comment. This is a comment. This is a comment. This is a comment. This is a comment. This is a comment. This is a comment. */
|
|
|
|
|
|
|
|
Naming Convention
|
|
*****************
|
|
|
|
ASM-NC-01: Lower case letters shall be used for case insensitive names
|
|
======================================================================
|
|
|
|
This rule applies to assembler directive, instruction prefix, instruction
|
|
mnemonic, and register name.
|
|
|
|
Compliant example::
|
|
|
|
.code64
|
|
lock and %rcx, (%rdx)
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
.CODE64
|
|
LOCK AND %RCX, (%RDX)
|
|
|
|
|
|
ASM-NC-02: Names defined by developers shall use lower case letters
|
|
===================================================================
|
|
|
|
Names defined by developers shall use lower case letters with the following
|
|
exception. If an object-like MACRO is defined with '#define', it shall be named
|
|
with full upper case.
|
|
|
|
Compliant example::
|
|
|
|
asm_showcase:
|
|
movl $0x1, %eax
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
ASM_SHOWCASE:
|
|
movl $0x1, %eax
|
|
|
|
|
|
ASM-NC-03: Label name shall be unique
|
|
=====================================
|
|
|
|
Label name shall be unique with the following exception. Usage of local labels
|
|
is allowed. Local label is defined with the format 'N:', where N represents any
|
|
non-negative integer. Using 'Nb' to refer to the most recent previous definition
|
|
of that label. Using 'Nf' to refer to the next definition of a local label.
|
|
|
|
Compliant example::
|
|
|
|
asm_showcase_1:
|
|
movl $0x1, %eax
|
|
|
|
asm_showcase_2:
|
|
movl $0x2, %eax
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_showcase:
|
|
movl $0x1, %eax
|
|
|
|
asm_showcase:
|
|
movl $0x2, %eax
|
|
|
|
|
|
ASM-NC-04: Names defined by developers shall be less than 31 characters
|
|
=======================================================================
|
|
|
|
Compliant example::
|
|
|
|
asm_showcase:
|
|
movl $0x1, %eax
|
|
|
|
.. rst-class:: non-compliant-code
|
|
|
|
Non-compliant example::
|
|
|
|
asm_showcase_asm_showcase_asm_showcase:
|
|
movl $0x1, %eax
|
|
|
|
|