x86 어셈블리 예제

어셈블리 언어로 레지스터를 참조할 때 이름은 대/소문자를 구분하지 않습니다. 예를 들어 EAX 및 eax 이름은 동일한 레지스터를 참조합니다. C 코드를 컴파일할 때 어셈블리 코드로 변환되고 궁극적으로 기계 코드로 변환됩니다. 호출 규칙은 C 함수가 인수를 수신하고 스택 및/또는 레지스터에 값을 배치하여 값을 반환하는 방법을 정의합니다. 호출 규칙은 다른 C 함수를 호출하는 C 함수, C 함수를 호출하는 어셈블리 코드 조각 또는 어셈블리 함수를 호출하는 C 함수에 적용됩니다. (임의의 어셈블리 코드를 호출하는 어셈블리 코드에는 적용되지 않습니다. 이 경우 제한은 없습니다.) 즉, 어셈블리의 데이터를 정수 및 부동 점의 두 가지 범주로 그룹화할 수 있습니다. 부동 점 값을 레지스터에 로드하고 정수처럼 처리할 수 있지만 결과는 예기치 않은 것이므로 별도로 유지하는 것이 가장 좋습니다. 비트 이동 및 회전 명령은 시프트할 값에 대해 32비트 레지스터를 사용하며, 시프트 개수에 대해 고정된 8비트 레지스터 cl을 사용합니다. 예를 들어 shll %cl, %ebx는 ebx = ebx << cl;를 의미합니다. 비교 지침은 범용 레지스터를 변경하지 않고 eflags에 영향을 미칩니다. 예를 들어 cmpl %eax, %ebx는 이름 없는 임시 장소에서 빼서 두 레지스터의 값을 비교하고 결과에 따라 플래그를 설정하므로 eax ebx가 서명되지 않은 모드 또는 서명된 모드에서 ebx인지 여부를 알 수 있습니다.

마찬가지로, testl %eax, %ebx는 임시 장소에서 eax 및 ebx를 계산하고 그에 따라 플래그를 설정합니다. 대부분의 경우 비교 후의 명령은 조건부 점프입니다(나중에 다룹니다). 예를 들어, 몇 가지 산술 명령은 하나의 레지스터만 인수로 사용합니다: 명령 포인터에 쓰는 것은 간단합니다 – jmp 명령은 명령 포인터를 대상 주소로 설정하므로 예를 들어 다음과 같은 시퀀스가 내용을 넣습니다. eax의 eax: “문자열” 명령의 클래스는 esi 및 edi 레지스터를 메모리 주소로 사용하고 명령 후 자동으로 증분/감소합니다. 예를 들어, movsb %esi, %edi는 *edi = *esi를 의미합니다. esi++; edi++; (1바이트 복사).

Posted in Uncategorized