Link: https://yozm.wishket.com/magazine/detail/2483/
제목 : 프론트엔드 개발자가 알아야할 ‘유닛 테스트’ 작성법
내용
테스트의 본질은 ‘검증하고 싶은 무언가를 검증하는 것’이다. 검증하는 것이 어떤 것이냐에 따라 목표나 이름이 달라진다.
Opinion
테스트 코드 관련해서는 여러번 시도해본적이 있지만 실제 프로젝트에 적용해본적은 아직 없다. 필요성에 아직 공감을 깊게 못해고 있다는 점이 큰 것 같다. 그래서 올해 중순에 있을 나만무 시즌에는 서비스 크기나 FE쪽 기술 난이도를 고려해서 테스트 코드 관련해서 적극 도입을 검토해볼 예정이다.
가장 많이 사용되는 인스트럭션은 데이터를 한 위치에서 다른 위치로 복사하는 명령이다.
오퍼레이션 표기 방식의 일반성으로 인해 데이터 이동과 관련된 기계어 인스트럭션의 간단해졌다.
데이터 이동 클래스 MOV는 4개의 인스트럭션을 구분되어 있다.: movb
, movw
, movl
, movq
. 이 네개의 인스트럭션은 모두 같은 동작을 하지만 인스트럭션의 마지막 글자에 따라 서로 다른 크기의 데이터를 다룬다는 점에서 차이가 있다.
소스 오퍼랜드는 상수, 레지스터 저장값, 메모리 저장 값을 표시한다.
목적 오퍼랜드는 메모리 또는 레지스터 주소의 위치를 지정한다.
x86-64는 데이터 이동 인스트럭션에서는 소스 값을 레지스터에 적재하는 인스트럭션과 레지스터 값을 목적지에 쓰기위한 인스트럭션이 필요하다.
Instruction | Effects | Description |
---|---|---|
MOV S, D | D ←S | Move |
movb | Move Byte | |
movw | Move word | |
movl | Move double word | |
movq | Move quad word | |
movabsq I , R | R ←I | Move absolute quad word |
movabsq
의 경우 64비트 상수를 다루기 위한 것이다. movq
의 경우 32비트 2의 보수 숫자로 나타낼 수 있는 상수 소스 오퍼레이션만 가지며 이후 부호 확장 되어 목적지를 위해서 64비트를 생산하게 된다. movabsq의 경우 임으로 64비트 상수 값을 소스 오퍼레이션으로 가질 수 있고, 목적지를 레지스터만으로 설정 가능하다.
작은 소스 값을 큰 목적지로 복사하기 위한 MOVZ 클래스와, MOVS 클래스가 있다. 이 인스트럭션들은 레지스터나 메모리에 있는 소스로 부터 레지스터 목적지로 복사한다. 두 클래스 인스트럭션의 마지막 두 개의 문자는 각각 소스의 크기와 목적지의 크기를 나타낸다.
Instruction | Effects | Description |
---|---|---|
MOVZ S, R | R ←ZeroExtend(S) | Move with zero extension |
movzbw | Move zero-extended byte to word | |
movzbl | Move zero-extended byte to double word | |
movzwl | Move zero-extended word to double word | |
movzbq | Move zero-extended byte to quad word | |
movzwq | Move zero-extended word to quad word |
movzlq
인스트럭션은 없다. 해당 데이터 이동은 movl
로 구현 가능하다.Instruction | Effects | Description |
---|---|---|
MOVS S, R | R ←SignExtend(S) | Move with sign extension |
movsbw | Move sign-extended byte to word | |
movsbl | Move zero-extended byte to double word | |
movswl | Move sign-extended word to double word | |
movsbq | Move sign-extended byte to quad word | |
movswq | R ←I | Move zero-extended word to quad word |
movslq | R ←I | Move sign-extended double word to quad word |
cltq | %rax ← SignExtend(%eax) | Sign-extend %eax to %rax |
cltq
인스트럭션의 경우 레지스터 %eax
와 %rax
만을 대상으로 한다.x86-64에서 프로그램 스택은 특정 영역에 위치의 주소를 갖는 형태로 아래로 성장하는 특징이 있다.
popq 인스트럭션은 데이터를 추출하고 pushq 인스트럭션은 데이터를 스택에 추가하는 기능을 제공한다.
subq $8, %rsp -> Derement stack pointer
movq %rbp, (%rsp) -> Store %rbp on stack
movq (%rsp), %rax -> Read %rax from stack
addq $8, %rsp -> Derement stack pointer
프로지서 호출은 소프트웨어에서의 주요 추상화이다. 지정된 인자들과 리턴 값으로 특정 기능을 구현하는 코드를 감싸주는 방법을 제공한다.
프로시저를 통해 프로그램 상태에 무슨 효과를 갖는지 간결한 인터페이스를 제공하며, 동시에 구체적인 구현을 감춰주는 추상화 매커니즘으로서 이용한다.
프로시저가 기계어 지원을 제공할 때 아래와 같은 메커니즘과 연관된다.
대부분의 언어에서 프로시저 호출 동작 방식을 스택 자료구조의 후입선출 방식을 가지고 있다. 프로시저 가 다른 프로시저를 호출하는 경우 호출한 프로시저가 일시 중지되고 이후 호출된 프로시저가 리턴했을 때 자신이 할당된 위치로 반납될 수 있다. 따라서 스택을 통해 프로시저들이 요구하는 저장 장소로 활용될 수 있으며, 여기서 스택과 프로그램 레지스터들이 제어와 데이터를 전송하기 위해, 메모리를 할당하기 위해 필요한 정보를 저장한다.
프로시저가 레지스터에 저장할 수 있는 개수 이상의 저장 공간을 필요로 할때 스택에 할당한다. 이때 사용되는 영역을 스택 프레임이라고 한다.
일반적인 스택과 달리 stack Top 부분이 바닥을 향해 있으며, 실행중인 프로시저에 대한 프레임은 항상 스택의 시작 부분, 맨 위에 위치한다. 프로시저(P)가 다른 프로시저(Q)를 부를 때 다시 프로그램이 재실행되는 위치에 대한 리턴 주소를 보관하게 된다. 이때 피호출 프로시저(Q)가 아닌 호출 프로시저(P)와 관련있는 정보기 때문에 호출 프로시저(P)의 스택 프레임에 속한다.