• 동기
    • 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 도 들어가기 때문이다.