मुख्य कंटेंट तक स्किप करें

인라인 어셈블리

소개

이 문서는 Wave 언어의 인라인 어셈블리에 대해 다룹니다. 인라인 어셈블리는 Wave가 제공하는 기능 중 하나로, 고수준 언어의 편의성을 유지하면서도 저수준 하드웨어 제어에 직접 접근할 수 있는 극단적인 수준의 문법입니다.

즉, 일반적인 Wave 코드로는 다루기 어려운 레지스터 조작, 메모리 직접 접근, 특수 명령어 실행 등을 가능하게 하며, 성능 최적화나 하드웨어 종속적인 작업이 필요할 때 활용됩니다.


기본 문법

asm {
"어셈블리 명령어" // 실제 어셈블리 코드 (한 줄에 한 명령어)
...
in("레지스터") 값 // 입력 레지스터 매핑
out("레지스터") 변수 // 출력 레지스터 매핑
}

문법 요소

  1. 어셈블리 명령어

    • "..." 문자열 형태로 작성하며, 실제 CPU에서 실행되는 저수준 어셈블리 명령어 입니다.
    • 여러 줄 작성 가능하며, 한 줄에 한 개의 명령어를 작성합니다.
    • 예시:
      "mov rax, 1"
      "syscall"
  2. in("레지스터") 값

    • 변수(또는 표현식)의 값을 지정한 레지스터에 로드합니다.
    • 예시:
      in("rdi") s
      -> 변수 s의 값을 x86-64 규약에서 첫 번째 syscall 인자 레지스터인 rdi에 넣음.
  3. out("레지스터") 변수

    • 지정한 레지스터의 값을 Wave 변수로 가져옵니다.
    • 예시:
      out("rax") ret
      -> syscall의 반환값이 저장된 rax 레지스터 값을 변수 ret에 저장.

간단한 예제

fun main() {
var msg_ptr: ptr<i8> = "Hello from syscall!\n";
var ret_val: i64;

asm {
"mov rax, 1"
"syscall"
in("rdi") 1
in("rsi") msg_ptr
in("rdx") 20
out("rax") ret_val
}
}

주의사항

  • 인라인 어셈블리는 Wave의 타입 안정성을 우회하므로, 잘못된 멸영어 사용 시 프로그래밍이 비정상 종료되거나 undefined behavior가 발생할 수 있습니다.
  • in, out 매핑은 컴파일 타임에 검증되지만, 명령어 자체의 유효성은 보장하지 않습니다.