테스트 환경
- Intel CPU
- Windows10
- 32bits
- 참고로 어셈블리 테스트의 경우 .c로 파일을 만들어 테스트하자
// inline_asm1.c
#include <stdio.h>
int Add(int a, int b)
{
int c = a + b;
return c;
}
int main()
{
int n = 0;
// 스택에 매개변수 1, 2를 넣을 것
n = Add(1, 2);
// 반환 값은 EAX 레지스터에 담겨서 돌아 올 것
printf("result : %d\n", n);
// 이걸 기계어로 직접 표현하고 싶은데...
}
해보자.
VS의 인라인 어셈블리를 사용하면 되고, 주의할 점은 32bits만 지원한다.
// Example
// 어셈블리언어를 쓸때는 __asm을 쓰면된다
__asm
{
// eax 레지스터에 있는 값을 n으로 옮겨주세요
mov n, eax
}
// inline_asm1.c
#include <stdio.h>
int Add(int a, int b)
{
// 여기를 어셈블리언어로 아에 변경해 보자
int c = a + b;
return c;
}
result : 3
// inline_asm1.c
#include <stdio.h>
int Add(int a, int b)
{
int c = a + b;
__asm
{
mov eax, c // return c 과 동일하다
}
}
int main()
{
int n = 0;
Add(1, 2);
printf("result : %d\n", n);
}
함수 호출(매개변수 전달)을 어셈블리어로 표현해보자
// inline_asm1.c
#include <stdio.h>
int Add(int a, int b)
{
return a + b;
}
int main()
{
int n = 0;
//n = Add(1, 2);
__asm
{
push 2
push 1 // push를 이용해 스택을 할당
call Add // Add 함수 호출
add esp, 8 // (이 부분이 없으면 프로그램이 죽음)
// 역할은 할당된 스택을 제거한다.(일단은 받아들이자.)
mov n, eax
}
printf("result : %d\n", n);
}
어셈블리 파일로 만들어서 빌드해보기
#include <stdio.h>
int asm_main(); // 어셈블리 파일로 만들예정
int main()
{
int n = asm_main();
printf("result : %d\n", n);
}
; asm1.asm ; (참고) 어셈블리는 세미콜론이 주석
.model flat ; 이건 일단 받아들이고
public _asm_main
.code
_asm_main: ; 메인은 여기이다
mov eax, 100 ; return 100과 동일
ret
end
.asm 빌드방법은 세 가지 이다.
- command line 빌드
- 사용자 지정빌드 명령 추가로 빌드
- 빌드 종속성 추가로 빌드
command line 빌드
$ cl main.c /c # main.obj 생성됨
$ ml asm1.asm /c # asm1.obj 생성됨
$ link main.obj asm1.obj # .obj를 링킹
/c
: 링크없이 컴파일만 해달라
사용자 지정빌드 명령 추가로 빌드
.asm파일 우클릭 후 속성
모든 asm파일에 이렇게 해야하나? 100개, 1000개면?? -> 3번째 방식으로 해결
빌드 종속성 추가로 빌드
.asm을 자동으로 인식하게 해보자
참고로 기존에 생성된 .asm파일의 경우 우클릭 -> 속성을 들어가서 일반 -> 항목 형식을 Microsoft Macro Assembler로 수정해줘야함(만약에 위 설정후 asm파일을 만들었다면 안해도 됨)