Skip to the content.

AND 명령어 (Bitwise AND), ANDS

Summary

정의: 두 오퍼랜드의 비트 단위 논리곱(AND) 연산을 수행하여 결과를 레지스터에 저장하는 명령어. 조건 플래그 갱신 여부에 따라 ANDANDS 두 가지 변형이 존재함.


기본 문법

AND  Xd, Xn, Xm                    // 레지스터 간 AND
AND  Xd, Xn, #imm                  // 즉치값(비트마스크)과 AND
AND  Xd, Xn, Xm, {shift #amount}   // shift 적용 후 AND

32비트 버전: W 레지스터 사용 시 동일한 문법으로 32비트 연산 수행 (AND Wd, Wn, Wm)


AND vs ANDS 차이

니모닉 플래그 갱신 용도
AND 갱신 안 함 순수 비트 연산, 값 저장만 필요할 때
ANDS NZCV 플래그 갱신 연산 결과로 조건 분기를 하고 싶을 때

ANDS 플래그 규칙:

참고: TST 명령어는 사실 ANDS의 별칭(alias)으로, 결과를 저장할 필요 없이 플래그만 확인할 때 ANDS XZR, Xn, Xm 형태로 내부 처리됨.


즉치값(Immediate) 사용 시 제약 사항 — 자주 안 보이는 이유

핵심: AND 명령어의 즉치값(#imm)은 일반 정수가 아니라 “bitmask immediate”라는 특수한 인코딩 규칙을 따름.

제약 조건:

이유: ARM64 명령어는 고정 32비트 길이이므로, 64비트 즉치값을 명령어 안에 직접 담을 공간이 없음. 그래서 “규칙적인 비트 패턴”만 압축 인코딩하여 담을 수 있도록 설계됨.

결과적 영향: 컴파일러는 임의의 마스크 값을 AND하려 할 때 즉치값 인코딩이 불가능하면, 별도로 MOV(또는 MOVZ/MOVK)로 레지스터에 값을 로드한 뒤 레지스터-레지스터 AND를 사용함. 이 때문에 실제 어셈블리에서 “AND + 즉치값” 조합보다 “MOV + AND” 조합이 더 자주 관찰됨 → 질문하신 “자주 볼 것 같은데 자주 못 봄” 현상의 핵심 원인.


예제 코드

기본 AND 연산:

.global _start
.align 2

.text
_start:
    mov x0, #0xFF        // x0 = 0x000000FF
    mov x1, #0x0F         // x1 = 0x0000000F

    and x2, x0, x1         // x2 = 0xFF & 0x0F = 0x0F

    mov x0, #0
    mov x16, #1
    svc #0x80

ANDS를 이용한 조건 분기 (비트 검사):

.text
_start:
    mov x0, #0b1010        // x0 = 10 (이진수)

    ands xzr, x0, #0b0001    // 최하위 비트 검사, 결과는 버림(xzr)
    b.eq even_number         // 결과가 0이면(Z=1) 짝수

    // 홀수 처리
    mov x1, #1
    b   end

even_number:
    mov x1, #0

end:
    mov x0, #0
    mov x16, #1
    svc #0x80

Shift 적용 예시:

    and x2, x0, x1, lsl #4    // x1을 4비트 왼쪽 시프트 후 x0와 AND

실전 활용 패턴

용도 예시
특정 비트 마스킹 and x0, x0, #0xFF (하위 8비트만 추출)
정렬 확인 (Alignment) ands xzr, x0, #0xF → 16바이트 정렬 여부 검사
플래그 비트 검사 tst x0, #(1<<3) (특정 비트 set 여부 확인)
짝수/홀수 판별 tst x0, #1

MOV+AND 조합 실제 예시 (컴파일러 생성 패턴)

임의 마스크 값 사용 시 컴파일러가 생성하는 전형적 패턴:

mov  x1, #0x5678
movk x1, #0x1234, lsl #16    // 임의의 32비트 마스크 값 구성
and  x0, x0, x1                // 레지스터 간 AND 수행

결론: AND 자체는 기본적인 논리 연산이라 개념적으로는 친숙하지만, 즉치값 인코딩 제약으로 인해 실제 바이너리 분석 시 “AND 단독 명령”보다 “MOV/MOVK + AND” 조합, 또는 플래그 검사 목적의 TST(ANDS의 별칭) 형태로 더 자주 관찰되는 명령어임.