• C 로 작성하여 assembly 프로그램 만들기
  • 첫번째 어셈블리어 프로그램을 C로 프로그램하고 C compiler 를 이용 어셈블리어로 만들어 비교하여 보자
    test.c 의 이름으로 다음의 C 프로그램을 작성

    int A=2, B=5, SUM;
    main()
    {
        SUM = A + B;
    }

    Turbo-C 2.0 compiler 에서 tcc -S test.c 하면 test.asm 이 만들어짐
     
     
    책의 어셈블리 프로그램
    C로 프로그램하고 어셈블리어로 만든 프로그램
    (Turbo-C compiler 2.0 에서 assembly 로 만듦)
    TITLE PGM1_1: SAMPLE PROGRAM                   
     .MODEL SMALL                   
     .STACK   100H                   

     .DATA                   
     A DW     2                   
     B DW     5                   
     SUM DW   ?                   

     .CODE                   
     MAIN     PROC                   
     ;initialize DS                   
         MOV  AX,@DATA                   
         MOV  DS,AX                   
     ;add the numbers                   
         MOV  AX,A      ;AX has A          
         ADD  AX,B      ;AX has A+B          
         MOV  SUM,AX    ;SUM = A+B          
     ;exit to DOS                   
         MOV  AX,4C00H                   
         INT  21H                   
     MAIN ENDP                   
     END  MAIN     

        .186      
        ifndef  ??version      
    ?debug  macro      
        endm      
        endif      
        ?debug  S "main.c"      
    _TEXT   segment byte public 'CODE'      
    DGROUP  group   _DATA,_BSS      
        assume  cs:_TEXT,ds:DGROUP,ss:DGROUP      
    _TEXT   ends      
    _DATA   segment word public 'DATA'      
    d@  label   byte      
    d@w label   word      
    _DATA   ends      
    _BSS    segment word public 'BSS'      
    b@  label   byte      
    b@w label   word      
        ?debug  C E9906D7824066D61696E2E63      
    _BSS    ends      
    _DATA   segment word public 'DATA'      
    _A  label   word      
        dw  2      
    _B  label   word      
        dw  5      
    _DATA   ends      
    _TEXT   segment byte public 'CODE'      
        ?debug  C E800066D61696E2E63906D7824      
        ?debug  L 2      
    _main   proc    near      
        ?debug  B      
        ?debug  B      
        ?debug  L 4      
        mov ax,word ptr DGROUP:_A      
        add ax,word ptr DGROUP:_B      
        mov word ptr DGROUP:_SUM,ax      
    @1:      
        ?debug  L 5      
        ret      
        ?debug  E      
        ?debug  E      
    _main   endp      
    _TEXT   ends      
    _BSS    segment word public 'BSS'      
    _SUM    label   word      
        db  2 dup (?)      
    _BSS    ends      
        ?debug  C E9      
    _DATA   segment word public 'DATA'      
    s@  label   byte      
    _DATA   ends      
    _TEXT   segment byte public 'CODE'      
    _TEXT   ends      
        public  _main      
        public  _SUM      
        public  _B      
        public  _A      
        ?debug  C EA0109      
        ?debug  C E31800000023040000      
        ?debug  C EC055F6D61696E1800      
        ?debug  C EC045F53554D0400      
        ?debug  C EC025F420400      
        ?debug  C EC025F410400      
        end      
     
     

  • C 프로그램의 변수명이나 함수명은 어셈블리로 변환시 모두 변수명이나 함수명앞에 _가 붙습니다.
  • C 프로그램에서 global variable 로 선언한 변수가 초기값을 갖지 않을경우 이는 BSS (uninitialized data area)

  • 영역에 할당됩니다. 위의 예어서 SUM 은 초기값이 없음으로 BSS 영역에 할당되었습니다.
  • 그외 소스레벨 debugging을 하기위한 정보들이 들어가 있습니다.

  •  
  • 위의 C로 프로그램한후 Turbo-C compiler 에 의해 만들어진 assembly 프로그램은 assembler 로 실행화일을

  • 만들어서 바로 돌릴수가 없습니다. 왜냐하면 C compiler 는 사용자가 프로그램한 프로그램에 여러가지 시작및
    종료와 관련된 (주로 메모리관리 및 작업환경정보등) 프로그램을 덧붙이기 때문입니다.
    그러므로 dos 로 돌아가는 명령으로 종료가 구현되지 않고 ret 명령으로 call 한프로그램으로 복귀후 복귀
    프로그램에서 dos 로 return 하기때문입니다.
     
  • 위의 C 프로그램을 Turbo-C compiler 에서 실행화일을 만들었을때의 크기는 2,314 byte 가 됩니다.

  • (프로그램 크기는 옵션이나 compiler 에 따라 다를수 있음)
    이는 고급언어는 프로그램의 작업환경, 메모리 사용, 파일제거등 PSP에 관련된 모든것을 스스로 해결하기때문입니다.
  • 어셈블리로 프로그램한 후 실행화일을 만들면 536 byte 입니다.

  •  

    Program Segment Prefix (PSP)

  • PSP 란?

  •  
      DOS 가 프로그램을 로드할때 사용자 프로그램앞 256바이트 (100H 바이트) 에 PSP 라 불리는 제어블럭을 로드한다.
      PSP 는 DOS가 프로그램 실행을 돕기위해 사용하는 여러가지 정보를 가지고 있다.
      이러한 정보는 사용한 언어에 관계없이 모든 DOS 프로그램에 필요하지만 고급언어는 프로그램의 작업환경,
      메모리 사용, 파일제거등 PSP에 관련된 일을 스스로 해결함으로 어셈블리어에서 보다 더 중요하다.
     
  • PSP의 내부구조
    •  
       
      Offset
      Size
      Item
      00h Word Program exit point (INT 20h.) 
      02h Word Memory size in paragraphs. 
      04h Byte Unused. 
      05h 5 Bytes Far call to DOS function handler. 
      0Ah DWord Old INT 22h vector. 
      0Eh DWord Old INT 23h vector. 
      12h DWord Old INT 24h vector. 
      16h Word Parent PSP segment. 
      18h 14h Bytes Open files (0FFh = unused.) 
      2Ch Word Environment segment. 
      2Eh DWord Far ptr to SS:SP. 
      32h Word Max. open files. 
      34h DWord --> Open files table (usually PSP:0018h.) 
      38h 8 Bytes ? 
      40h Word Version number reported to this process (DOS 5+.) 
      42h 0Eh Bytes ? 
      50h 3 Bytes DOS function dispatcher (INT 21h, RETF.) 
      53h Word Unused. 
      55h FCB #1 extension. 
      5Ch FCB #1. 
      6Ch FCB #2. 
      80h 80h Bytes Command line tail. 
       
      예) debug pgm1_1.exe 를 수행후 PSP 를 살펴보자
       
       
      -r  
      AX=0000  BX=0000  CX=0018  DX=0000  SP=0100  BP=0000  SI=0000  DI=0000  
      DS=3160  ES=3160  SS=3172  CS=3170  IP=0000   NV UP EI PL NZ NA PO NC  
      3170:0000 B87131        MOV     AX,3171  
       
      CS 가 3170 임으로 PSP의 위치는 3160:0000
      -d 3160:0000 100  
      3160:0000  CD 20 FF 9F 00 9A F0 FE-1D F0 4F 03 22 29 8A 03   . ........O.")..  
      3160:0010  22 29 17 03 22 29 11 29-01 01 01 00 02 FF FF FF   ")..").)........  
      3160:0020  FF FF FF FF FF FF FF FF-FF FF FF FF 2B 31 4C 01   ............+1L.  
      3160:0030  2A 2D 14 00 18 00 60 31-FF FF FF FF 00 00 00 00   *-....`1........  
      3160:0040  07 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................  
      3160:0050  CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20   .!...........  
      3160:0060  20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20           .....  
      3160:0070  20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00           ........  
      3160:0080  00 0D 70 67 6D 31 5F 31-2E 65 78 65 0D 00 01 01   ..pgm1_1.exe....  
      3160:0090  01 01 01 01 01 01 01 01-01 01 01 01 01 01 01 01   ................  
      3160:00A0  01 01 01 01 01 01 01 01-01 01 01 01 01 01 01 01   ................  
      3160:00B0  01 01 01 01 01 01 01 01-01 01 01 01 01 01 01 01   ................  
      3160:00C0  01 01 01 01 01 01 01 01-01 01 01 01 01 01 01 01   ................  
      3160:00D0  01 01 01 01 01 01 01 01-01 01 01 01 01 01 01 01   ................  
      3160:00E0  01 01 01 01 01 01 01 01-01 01 01 01 01 01 01 01   ................  
      3160:00F0  01 01 01 01 01 01 01 00-00 00 01 00 00 00 1C 61   ...............a  
      3160:0100  B8                                                .  
       
      CD 20 은 INT 20H 의 기계어임.  
      9FFF 는 메모리 크기임(40959 * 16 = 655344).  
      312B 은 환경변수 있는곳.  
      9A 는 call 의 기계어.  
      0080 이후로 program 이름과 옵션이 들어감.
      -d 312B:0000  
      312B:0000  77 69 6E 62 6F 6F 74 64-69 72 3D 43 3A 5C 57 49   winbootdir=C:\WI  
      312B:0010  4E 44 4F 57 53 00 43 4F-4D 53 50 45 43 3D 43 3A   NDOWS.COMSPEC=C:  
      312B:0020  5C 57 49 4E 44 4F 57 53-5C 43 4F 4D 4D 41 4E 44   \WINDOWS\COMMAND  
      312B:0030  2E 43 4F 4D 00 50 52 4F-4D 50 54 3D 24 70 24 67   .COM.PROMPT=$p$g  
      312B:0040  00 50 41 54 48 3D 43 3A-5C 42 43 34 35 5C 42 49   .PATH=C:\BC45\BI  
      312B:0050  4E 3B 43 3A 5C 57 49 4E-44 4F 57 53 3B 43 3A 5C   N;C:\WINDOWS;C:\  
      312B:0060  57 49 4E 44 4F 57 53 5C-43 4F 4D 4D 41 4E 44 3B   WINDOWS\COMMAND;  
      312B:0070  43 3A 5C 4C 41 4E 47 55-41 47 45 5C 4D 41 53 4D   C:\LANGUAGE\MASM  
       
      환경변수가 저장되어 있는곳
      -u 3160:0000 1  
      3160:0000 CD20          INT     20  
       
      -u 3160:0005 5  
      3160:0005 9AF0FE1DF0    CALL    F01D:FEF0  
       
       

      참고사항

      • 메모리 사이즈 9FFF 는 십진수로 40959 이며 여기에 16을 곱한값이 메모리 사이즈임
      • 위의 debug 초기화면에서 보듯이 초기 DS 값은 3160 으로 되어있다.
      • 즉 초기 DS 값은 PSP 영역을 가리킨다.
      • 이를 사용자 프로그램의 데이타 영역으로 바꾸기 위하여  MOV AX, @DATA 와  MOV DS, AX 명령이 필요하다.