본문 바로가기
Embedded System/Assembly

Assembly syntax

by rewyear 2024. 2. 2.

Assembly syntax

ARM Assembly Language 관련 syntax에 대해서 정리한 글

 

Assembly Identifiers

.section <section_name>, "<option>"

섹션을 정의

 

.balign n

다음 주소가 n바이트 단위로 alignment

 

.global <variable_name or function_name>

.global 키워드를 사용하여 전역화

 

label without branch instruction

하기와 같이 예제코드에서 분기문이 없거나, 분기문이 실행되지 않는다면 순차적으로 다음 코드로 넘어감.

 

# example 1: 해당 예제의 경우 1번째 분기문에서 case1으로 분기되지 않은 경우 순차적으로 다음 code인 "add $s2, $s0, $s1 "로 진행

beq $s0, $s1, case1

add $s2, $s0, $s1

case1:

    sub $s1, $s1, $s0

 

# example 2) 해당 예제의 경우 3번째 분기문에서 case2로 분기되지 않은 경우 순차적으로 다음 code인 case1로 진행

add x1 x1 #4

cmp x0 x1

b.eq case2

case1:

    /* code1 */

case2:

    /* code2 */

 

 

inline assembly 키워드 __asm

C, C++ code 내에서 동작하는 assembly code를 작성하기 위해 사용하는 키워드.

  • Shifts the burden of handling the procedure call standard (PCS) from the programmer to the compiler. This includes allocating the stack frame and preserving all necessary callee-saved registers.
  • Inline assembly code gives the compiler more information about what the assembly code does.
  • The compiler can inline the function that contains the assembly code into its callers.
  • Inline assembly code can take immediate operands that depend on C-level constructs, such as the size of a structure or the byte offset of a particular structure field.

__asm

기본적인 형태는 다음과 같다.

 

/* essential syntax */

__asm [volatile] (code);

 

 /* Extended inline assembly syntax */

__asm [volatile] (code_template

: outputs

[: inputs

[: clobber_list]]

);

  • code: assembly instruction
  • code_template: 확장된 assembly 명령어, 템플릿 변수를 사용하게 되면 ':'으로 나뉜 outputs, inputs, clobber_list에 템플릿 변수에 대한 정의를 해주어야함.

outputs and inputs

[<name>] "<constraint>" (<value>) 형태로 작성되며

  • [<name>]: code templete의 변수를 지정하며, 별도로 명시적으로 지정하지 않을 경우 code templete에서는 %n형태로 0부터 순서대로 사용
  • "<constraint>": 해당 operand의 속성 설정
  • (<value>): C code 형태의 변수 지정

ex)

void saturating_add(int a, int b)

{

    int result;

    __asm("qadd %0, %[lhs], %[rhs]" : "=r" (result) : [lhs] "r" (a), [rhs] "r" (b) );

    return result;

}

 

clobber list

  • “memory”: 컴파일러에게 해당 asm code가 단순 변수(register)가 아닌 메모리를 수정할 것이라는 것을 알림.
  • “cc”: 컴파일러에게 해당 asm code가 condition flags를 변경할 것이라는 것을 알림

 

 

Constraints

컴파일러가 하기와 같이 지정한대로 해당 operand에 대한 속성 값을 사용

  • r: 해당 operand에 대해 64bit general purpose register를 사용(X0-X30)
  • w: for SIMD or floating point(V0-V31)
  • x: for 128-bit vector(V0-V15)

Constraint modifiers

모든 output operand는 constraint modifier를 기재해 주어야 함.

  • "=": write only, 모든 input operand가 read된 이후에만 write 가능
  • "+": both read and write
  • "=&": write only, 모든 input operand가 read되기 전에도 수정가능
  • "+&": both read and write, 모든 input operand가 read되기 전에도 r/w 가능

&: "earlyclobber" operand를 나타내고 input operand를 사용하는 명령이 끝나기 전에 변경 된다는 것을 의미함.
그래서 input operand나 메모리 어드레스의 일부을 나타내는 register에는 못 쓴다.
gcc는 input 변수가 다 사용되고 나면 output에 사용된다고 가정하기 때문에 input에 사용된 변수가 output과 같게 되고 또 output이 input 보다 먼저 사용되는 경우가 발생할 수 있다. 이런 경우를 막기 위해 output에 사용된 변수가 input이 모두 사용되기 전에 변경될 수도 있다고 알려줘야만 input과 output이 같아져 생기는 에러를 막을 수 있다.

 

 

Templete Modifiers

%U

The asm statement must also use %U as a placeholder for the “update” flag in the corresponding load or store instruction.

 

예제

Correct

    asm ("st%U0 %1,%0" : "=m<>" (mem) : "r" (val));

Wrong

    asm ("st %1,%0" : "=m<>" (mem) : "r" (val));

300x250

'Embedded System > Assembly' 카테고리의 다른 글

WFI / WFE  (0) 2024.06.27