관리 메뉴

Bull

[ARM::kernel] 어셈블리에서 레이블을 왜 자주 사용하는 걸까? (C에서는 피하라고 배웠었다) 본문

Computer Science/ARM

[ARM::kernel] 어셈블리에서 레이블을 왜 자주 사용하는 걸까? (C에서는 피하라고 배웠었다)

Bull_ 2024. 9. 1. 12:54

linux kernel 공부 중 어셈블리 코드가 적힌 부분에는 레이블이 많은 이유가 궁금했다. 하지만 나는 C에서는 레이블로 강제 점프하는 행동을 되도록이면 피하라고 배웠었다. 그 차이를 알아보자.

C 언어에서의 레이블

int main() {
    int x = 0;

    if (x == 0)
        goto error;

    // 정상적인 코드 실행 흐름
    return 0;

error:
    // 오류 처리 코드
    return -1;
}

C에서 goto와 레이블을 사용하는 것은 가독성을 떨어뜨리고, 코드의 유지보수를 어렵게 만들 수 있기 때문에 일반적으로 권장되지 않는다. 특히, 프로그램의 흐름이 복잡해지면 goto를 따라가기가 어려워지고, 코드의 흐름이 비직관적이게 된다. 그래서 C 언어에서는 레이블과 goto의 사용을 피하고, 대신 함수, 루프, 조건문 등을 사용해 명확한 제어 흐름을 유지하는 것이 좋다고 권장된다.

어셈블리에서의 레이블

반면, 어셈블리 언어에서는 레이블이 필수적인 요소다. 어셈블리 언어는 고급 언어처럼 복잡한 제어 구조를 제공하지 않기 때문에, 레이블은 코드의 흐름을 제어하고 특정 위치로 점프하기 위해 자주 사용된다.

loop_start:
    cmp r2, r3
    blo loop_start   @ r2 < r3이면 loop_start로 분기

여기서 loop_start는 루프의 시작을 나타내는 레이블이다. cmp 명령어가 비교 결과에 따라 조건부로 이 레이블로 다시 분기(blo 명령어)를 한다. 이런 레이블을 사용하는 것은 어셈블리 언어에서 매우 일반적이고, 필수적이다. 고급 언어의 제어 구조(예: if, while, for 등)를 어셈블리로 표현할 때 레이블과 분기 명령어가 자주 사용된다.

결론

C에서 레이블을 피하라는 이유는 코드의 로직이 꼬여서 버그가 발생하거나 그러한 이유가 아니라 유지보수와 가독성 때문이 피하라는 이유였다.코드적으로는 문제가 없는 사용방법이다. 그리고 우리가 OOP를 배우면 객체 지향을 원칙으로 하는 것처럼 C에서의 철학으로는 구조적 프로그래밍 원칙에 위배되기 때문이다. 따라서 C에서는 권장하지 않는 방법이었다. 어셈블리 코드에서는 이런 원칙이 없이 레이블을 필수적으로 사용된다고 판단했고 처음부터 그래왔으니까 사용되는 것 같다. 레이블이 없고 함수형 프로그래밍처럼 되어있었다면 일반적으로 사용되는 코드와 비슷했을 거 같다.