본문 바로가기
코스웨어/12년 내장형하드웨어

[Assembly] 8월 24일 업무일지 By.정철

by 알 수 없는 사용자 2012. 8. 24.
728x90
반응형

이 글을 병마와 싸우고 계신 지윤이햄을 위해 바칩니다 (_ _)

그리고 예비군가서 애니팡 하트 자꾸 날리는 동혁이도....


*C언어 부호확장 사례


#include <stdio.h>

int main()
{
  char A = 0xFF;
  
  printf("16 :: %02X\n", A);

  return 0;
}

<실행결과창>



printf에서 인자가 넘어갈때 부호확장이 일어난다.

signed -1의 경우 FF인데 부호확장시 (int로) FFFFFFFF가 되서 넘어간다.

우리는 char -1값인 FF가 필요한데

출력은 FFFFFFFF로 나온다. C로는 해결 할 수 없는 일이다.


이와 유사한 case로 C에서 fgetc()함수를 사용할때

파일의 끝일경우 EOF를 반환하게 되는데

fgetc가 int를 반환하지만 EOF는 char -1이다.


char형으로 변환하기 위해 앞에 3바이트를 자르게 되는데,

여기서 FFFFFFFF과 000000FF를 구분할 수 없게 된다.


*Calling Convention

-함수 호출 규약

:: 함수를 후출할 때 파라미터를 어떤 식으로 전달하고, 스택을 어떻게 정리하는가?

에 대한 일종의 규약이다.

(함수 호출전에 파라미터를 스택을 통해 전달한다는 것을 알아야 한다)

스택은 프로세스에서 정의된 메모리 공간이며 주소가 줄어드는 방향으로 자란다.

(스택은 PE header에 그 크기가 명시되어 있다.)

함수 호출 후에 ESP (스택 포인터)를 어떻게 정리하는지에 대한 약속이 바로

함수 호출 규약이다.


cdeclstdcall

-cdecl과 stdcall의 차이점은 인자를 스택에 넣는 순서와, 함수호출이 끝나고 스택에

있는 인자를 누가 지울건지로 갈린다.


스택에 인자를 넣는 순서는 위의 그림과 같다.

cdecl : 호출한 쪽에서 인자를 스택에서 지운다.

stdcall : 함수가 인자를 스택에서 지운다.


*MASM 컴파일

1. 준비물

위에 2개의 파일은 우리가 준비한 소스이다.

밑에 3개의 파일이 이제 준비물임.

io.h는 asm소스에서 include 하는 파일이다.

2개는 아직 잘 모르겠습니다.

c:\asm\software 에 가면 만날 수 있습니다.


윗줄은 asm파일만 컴파일 하는 방법

아랫줄은 실행파일을 만드는 방법이다.

자세한 사항은 나중에.. 나중에... 나중에.....


MASM 연습프로그램


.386            //32비트 이상 호환되도록
.MODEL FLAT     //메모리를 FLAT하다고 본다

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD
    //함수 선언(ExitProcess 함수이름) 원형 32비트 주소, 함수규약, 반환형(4바이트)
INCLUDE io.h  

cr  EQU  0Dh
Lf  EQU  0Ah          //define이다.

.STACK  4096          //스택 크기를 정한다. 노말 4096쓴다

.DATA                 //데이터 영역
number1  DWORD  ?     //4바이트, 초기값 없다
number2  DWORD  ?
prompt1  BYTE  "Enter First Number : "0  //1바이트, 문자열
prompt2  BYTE  "Enter Second Number : "0
string  BYTE  40  DUP  (?)    //1바이트 40개 복사한다 초기화 안된걸
label1  BYTE  cr, Lf, "The Sum is "    
sum  BYTE  11  DUP  (?)
  BYTE  cr, Lf, 0    //공간만 할당 받는다 label1 부터 밑으로 2줄은 같이 한덩어리다
 
.CODE                //코드 영역
_start:              //함수의 시작 _꼭 붙여줘야됨
  output  prompt1    //출력 메크로 (어셈블리 명령어 아님) 
  input  string, 40  //입력 메크로 (어셈블리 명령어 아님)
  atod  string       //ASCII to DECIMAL -> eax에 저장
  mov  number1, eax  //number1에 eax값 저장

  output  prompt2
  input  string, 40
  atod  string
  mov  number2, eax

  mov  eax, number1
  add  eax, number2   //n1 + n2
  dtoa  sum, eax      //문자열을 만들어서 sum에 넣어준다
  output  label1    
  
  INVOKE  ExitProcess, 0  //레지스터 원상복구 없으면 종료시에 에러난다

PUBLIC  _start        //start함수 밖에서 보이게


소스 분석내용입니다.

NASM과 모양이 약간 다르긴 하지만 그렇게 큰 차이가 없다.


*디버그 하기


윗줄은 asm파일 컴파일시 /Zi 옵션이 추가로 들어가야 한다.

아랫줄은 링크시에 /dubug 옵션이 추가로 들어간다.


컴파일이 끝나면 위의 2개의 파일이 나오게 됩니다.

그리고 아래 windbg.exe파일은 c:\asm\software 에 가면 만날 수 있습니다.


windbg.exe를 실행하고 Open Excutable을 실행한다.

F8 : step info

확인 하고 F8한번 더....

이런 창을 만날 수 있다.

왼쪽위 : 레지스터창 -> 현재 레지스터 값을 보여 준다.

아래창 : 메모리창 -> 현재 메모리 값을 보여준다. 변수 이름 앞에 &를 붙여주면 된다

(View 옵션에 가면 만날 수 있어요 ^_^)

이제 F8을 눌리면 프로그램이 한줄씩 실행되고,

즉각 레지스터와 메모리 값이 변경된다.


MASM 디버거는 지현이가 잘 정리했네요

MASM 디버거가 잘 안될 경우 시스템 변수에 path 추가해 주시면 됩니다.


오늘의 수업내용은 C에서 부호확장과

함수호출규약 cdecl과 stdcall

그리고 MASM 컴파일

MASM 디버깅에 대하여 배웠습니다.


오늘 공부용 소스와 파일들을 여기 올립니다. (_ _)

8024 Masm Debug.zip


728x90