C 언어의 프로그램의 간편성 과 assembly 언어의 빠른 실행등 두 언어의
장점을 살린다.
방법
1. inline assembly 를 이용하는 방법
C 프로그램내에 assembly 언어를 삽입
예1)
char const *message = "inline program example ...\n$";
main()
{
asm mov ah, 9
asm mov dx, message
asm int 21h
}
프로그램을 test1.c 로 저장후 Turbo-C 2.0 compiler 에서 tcc test1.c 하면
test1.exe 가 만들어짐
test1.exe를 수행하면 된다.
예2)
#include <stdio.h>
main()
{
int a,b,sum;
printf("Enter two values: ");
scanf("%d %d",&a,&b);
asm mov dx, WORD PTR a
asm add dx, WORD PTR b
asm mov WORD PTR sum, dx
printf("The sum is %d \n",sum);
}
2. C와 assembly 언어로 프로그램하고 함께 link
하는 방법
예 1) 단순한 function call
C 프로그램을 작성
#include <stdio.h>
int x,y,sum;
extern int myadd();
main()
{
x = 22;
y = 23;
myadd();
printf("x = %d, y = %d, sum = %d \n",x,y,sum);
}
프로그램을 lktest.c 로 저장
assembly 로 프로그램 작성
.MODEL SMALL
.DATA
EXTRN _x:WORD, _y:WORD, _sum:WORD
.CODE
PUBLIC _myadd
_myadd PROC NEAR
MOV AX,_x
ADD AX,_y
MOV _sum,AX
RET
_myadd ENDP
END
프로그램을 lktest2.asm 으로 저장
tcc lktest.c lktest2.asm 하면
lktest.exe 가 생성됨
lktest.exe 실행
예 2) C에서 assembly 로 파라메터 전달하기
C 프로그램을 작성
#include <stdio.h>
extern int myadd();
main()
{
int x = 22, y = 23, sum;
sum = myadd(x,y);
printf("x = %d, y = %d, sum = %d \n",x,y,sum);
}
프로그램을 lkparam.c 로 저장
assembly 로 프로그램 작성
.MODEL SMALL
.CODE
PUBLIC _myadd
_myadd PROC NEAR
PUSH BP ; BP의 내용이 변경됨으로 저장
MOV BP,SP ; SP 값을 BP 로 옮겨줌
PUSH DX ; 사용할 레지스터 값 저장
MOV DX, [BP+4] ; x 값을 스택에서 가져옮
ADD DX, [BP+6] ; y 값을 스택에서 갸져다가 더함
MOV AX, DX ; return 할 값은 AX에 저장
POP DX
POP BP
RET
_myadd ENDP
END
프로그램을 lkparam2.asm 으로 저장
tcc lkparam.c lkparam2.asm 하면
lkparam.exe 가 생성됨
lkparam.exe 실행
예 3) C에서 assembly 로 array 주소 전달하기
C 프로그램을 작성
int num[3]={0x10,0x20,0x30};
extern arrayadd();
main()
{
printf("sum of num array = %x \n", arrayadd(num));
}
프로그램을 array.c 로 저장
assembly 로 프로그램 작성
.MODEL SMALL
.CODE
PUBLIC _arrayadd
_arrayadd PROC NEAR
PUSH BP ; store BP to stack
MOV BP,SP ; BP points to stack top
PUSH SI ; store SI to stack
XOR AX, AX ; clear AX
MOV CX, 3 ; number of elements of array
MOV SI, [BP+4] ; near call, then [BP+4] points to
address of array
LOOP1:
ADD AX, [SI] ; add the array element
ADD SI, 2 ; 16bit data
LOOP LOOP1
POP SI
POP BP
RET
_arrayadd ENDP
END
프로그램을 array2.asm 으로 저장
tcc array.c array2.asm 하면
array.exe 가 생성됨
array.exe 실행
스택 동작의 설명
하나의 procedure 에서 다른 procedure 로 파라메터를 넘기는 방법중 하나가
스택을 이용한 방법이다
스택을 이용하는 방법은 call 하는 procedure에서 넘길 파라메터를 스택에
push 해주고 call된 procedure
에서 스택을 access 하여 이 파라메터를 이용한다.
call 된 procedure 가 끝날을때 call 한 procedure 로 return 하기위하여
return 할 주소도 스택에 넣어진다.
일반적으로 call 하는 방법은 call 되는 procedure 가 같은 세그먼트안에
있는 경우 (즉 NEAR type 으로
procedure 가 선언된경우) 와 다른 세그먼트에 있는경우 (즉 FAR type 으로
procedure 가 선언된 경우)
가 있다. NEAR type 일 경우는 call 되는 procedure 가 같은 세그먼트 안에
있음으로 IP 만 저장하면 되고
FAR type 인 경우 call 되는 procedure 가 다른 세그먼트안에 있음으로
CS:IP 모두를 저장해야만 한다.
그러므로 call 되는 procedure 가 NEAR 이면 IP 만 저장되고, FAR 이면
CS:IP 가 저장된다.
이러한 차이는 call 된 procedure 에서 파라메터를
가져올때의 offset 주소가 바뀜으로 주의하여야만 한다.
예) 위 예2 를 이용한 스택 동작 (NEAR 일경우)
(C 프로그램에서 call 하기 직전의
스택)
(C 에서 파라메터를 넘겨주는
모습 --- 뒷파라메터부터 스택에 넣는다)
(Assembly 프로그램에서의 스택의
모습, BP 값의 변화를 막기위해 PUSH 하고 POP 한다)
(스택에서 파라메터를 가져오는
모습)
만약 FAR type 으로 선언된 procedure 라면 MOV
DX, [BP+6] 을 통하여 x 값을 가져오고, MOV DX, [BP+8]
을 통하여 y 값을 가져온다.
이는 스택에 IP 뿐만 아니라 CS 도 들어가기 때문이다.