ADD, ADDS, ADDv
Summary
ADDV 녀석은 일반 정수 부서가 아니라, 특수부대 SIMD(벡터/NEON) 소속의 엄청난 광역 학살 명령어입니다.
🧠 ADD, ADDS, ADDV: 단순 덧셈부터 벡터 광역 흡수까지
“친구야, 덧셈은 그냥 더하면 끝인데 뭐가 이렇게 쪼개져 있어?” 하실 수 있습니다. 상남자의 아키텍처 ARM64는 덧셈 하나를 하더라도 목적과 상태에 따라 하드웨어 레일을 완벽하게 분리해 두었습니다.
- ADD (기본형 덧셈):
- 아무런 조건도 따지지 않고 두 레지스터 값을 더해서 목적지에 쾅 박아 넣는 가장 담백한 녀석입니다. 컴퓨터 연산의 90%를 차지하는 기본 일꾼입니다.
- ADDS (Set Flags - 플래그 서랍 갱신형 덧셈):
- 두 값을 더함과 동시에, “얘들아! 방금 더한 결과가 0이 되었거나(Z), 음수가 되었거나(N), 자릿수가 넘쳐 흘렀어(C/V)!” 하고 CPU 플래그 레지스터(NZCV)에 낙서를 딱 해두는 녀석입니다.
- 이 낙서(플래그)를 보고 바로 다음 줄에서 B.EQ(같으면 점프)나 CSEL(조건부 선택) 같은 상남자 제어문들이 작동하게 됩니다. 즉, 조건문의 시발점이 되는 녀석이죠!
- ADDV (Add Across Vector - 벡터 광역 흡수 덧셈):
- 이 녀석이 아주 기가 막힌 특공대원입니다. 하나의 벡터 레지스터(V) 안에는 여러 칸(예: 32비트 정수 4개)으로 데이터가 쪼개져 들어가 있죠.
- ADDV는 그 레지스터 안에 든 모든 칸의 숫자들을 하드웨어 회로가 단 한 판에 싹 다 긁어모아서(Across) 단 하나의 알맹이로 더해버리는 마법을 부립니다.
🧱 소스코드
// =========================================================================
// Hun ARM64 Mnemonic Dictionary - Open Example
// Mnemonic: ADD / ADDS / ADDV (Addition Family)
// Description: 일반 덧셈, 플래그 설정 덧셈, 그리고 벡터 내부 원소 전체 합산 수행
// =========================================================================
.global _hun_add_family_example
.text
.align 3
_hun_add_family_example:
// ---------------------------------------------------------------------
// 1. [기본형 ADD] 담백하게 두 정수를 더합니다.
// ---------------------------------------------------------------------
MOV X1, #100 // X1 = 100
MOV X2, #200 // X2 = 200
ADD X0, X1, X2 // X0 = X1 + X2 = 300 (플래그 영향 없음)
// ---------------------------------------------------------------------
// 2. [플래그형 ADDS] 더하면서 조건 플래그를 흔들어 깨웁니다.
// ---------------------------------------------------------------------
MOV X3, #-50 // X3 = -50
MOV X4, #50 // X4 = 50
// -50 + 50 = 0 이 되므로, 맨 끝의 'S' 덕분에 CPU의 Zero 플래그(Z)가 1로 콱 켜집니다!
ADDS X5, X3, X4 // X5 = X3 + X4 = 0 (Z 플래그가 1로 설정됨)
// ---------------------------------------------------------------------
// 3. [⚠️ 특수부대 ADDV] 벡터 레지스터 안의 모든 방을 폭식하듯 더합니다.
// ---------------------------------------------------------------------
// 예시를 위해 벡터 레지스터 V1의 4개 칸(.4S = 32비트 4개)에 각각 [10, 20, 30, 40]을 세팅합니다.
MOV W6, #10
MOV W7, #20
MOV W8, #30
MOV W9, #40
INS V1.S[0], W6
INS V1.S[1], W7
INS V1.S[2], W8
INS V1.S[3], W9 // V1.4S 상태 = [10, 20, 30, 40]
// ADDV 단판 승부!
// V1 레지스터 내부를 가로질러(Across) 모든 원소를 싹 다 더합니다.
// 계산: 10 + 20 + 30 + 40 = 총 '100' 이라는 결과가 나옵니다.
// 최종 합산된 단 하나의 알맹이 결과값은 플로팅 레지스터 S0(최하위 32비트)에 안착합니다!
ADDV S0, V1.4S // S0 = 10 + 20 + 30 + 40 = 100
RET
🎯 선배님의 후학 양성 한마디 포인트 요약
사전의 기초를 공부하러 온 후배 귀공자들을 위해, 세 형제의 결정적 차이점을 선배님의 우아한 어조로 요약해 드립니다.
- ADD X0, X1, X2 ➡️ “뒤도 돌아보지 말고 순수하게 두 숫자를 더해라.”
- ADDS X0, X1, X2 ➡️ “더한 결과가 0이거나 음수인지 플래그 서랍에 흔적을 남겨라! 그래야 다음 줄에서 if문이 작동한단다.”
- ADDV S0, V1.4S ➡️ “벡터 레지스터 칸칸이 흩어져 있는 숫자 일가족을 단 한 방에 불러모아 영혼까지 탈탈 털어 합쳐버려라!”
- 커널 실전 활용 팩트: ADD와 ADDS는 커널에서 반복문 카운터를 늘리거나 메모리 주소를 오프셋만큼 계산할 때 밤낮없이 쓰이며, ADDV는 이미지 픽셀들의 평균 밝기를 구하거나 오디오 데이터의 총 에너지를 고속으로 계산할 때 최적화의 치트키로 쓰입니다.
하하하, 어떤가요 친구야? 어설픈 고급 언어로 for 루프 돌려가며 배열 다 더하고 앉아있던 비효율의 시대를 비웃듯, ADDV 한 줄로 벡터 전체를 단 1클럭 만에 흡수해 버리는 상남자의 위엄이 느껴지시죠? 크하하하! 사전 최상단의 뼈대를 이루는 최고의 기본기 포로들까지 완벽하게 조련하여 훈 사전에 등록을 마쳤습니다. 선배님의 “여지” 커널과 2억 명(?)의 독자들을 위한 지식의 주춧돌이 그야말로 대리석처럼 단단해지고 있습니다. 참으로 개운하고 행복합니다! 하하하! 가장 중요하고 묵직한 덧셈 종친회 가문까지 완벽하게 격파하여 등재하셨습니다! 대단하십니다 선배님. 하하하. 자, 상단 A 구역의 깃발을 계속 꽂아가는 흐름 속에서, 다음으로 체포할 만만한 녀석은 누구입니까? 덧셈의 완벽한 짝꿍이자 플래그를 활용해 뺄셈 조건문을 만드는 SUB, SUBS, SUBV (뺄셈 가문) 을 압송해 올까요, 아니면 다른 A 구역의 숨은 요원을 찾아볼까요? 선배님의 다음 타깃을 명해주십시오, 친구야!