코스웨어/15년 스마트컨트롤러
20151007 - 권오민 - GPIO&AFIO / ASSEMBLY(C와 링크하기)
알 수 없는 사용자
2015. 10. 7. 12:47
◉GPIO & AFIO
●General-purpose and alternate-function I/Os
(GPIOs and AFIOs) - P.159
●GPIO functional description



●open-drain

http://terms.naver.com/entry.nhn?docId=755118&cid=42341&categoryId=42341
http://irmus.tistory.com/76
●GPIO functional description(continue)


●GPIO 실습
- 목표 : 스위치를 눌렀을 때는 Main보드에 LED만 켜지고 땠을 때는 Core보드에 LED만 켜져 있어야 한다.

- 소스
#define GPIOA_CRL (*(volatile unsigned int *)0x40010800) #define GPIOA_IDR (*(volatile unsigned int *)0x40010808) #define GPIOA_ODR (*(volatile unsigned int *)0x4001080C) #define GPIOA_BRR (*(volatile unsigned int *)0x40010814) #define GPIOA_BSRR (*(volatile unsigned int *)0x40010810) #define RCC_APB2ENR (*(volatile unsigned int *)0x40021018) #define GPIOC_CRH (*(volatile unsigned int *)0x40011004) #define GPIOC_IDR (*(volatile unsigned int *)0x40011008) #define GPIOC_ODR (*(volatile unsigned int *)0x4001100C) #define GPIOC_BRR (*(volatile unsigned int *)0x40011014) #define GPIOC_BSRR (*(volatile unsigned int *)0x40011010)
int main(void) { RCC_APB2ENR |= 0x14; //C:0001, A:1000이므로 14를 or한다. GPIOA_CRL = 0x44444441; GPIOC_CRH = 0x44414444; while(1) { if(!(GPIOA_IDR &0x04)) //Switch가 On되어 있다면, { GPIOA_BSRR = 0x01; //Core LED를 켠다. GPIOC_BRR = 0x1000; //Main LED를 끈다 } else //Switch가 Off되어 있다면, { GPIOA_BRR = 0x01; //Core LED를 끈다. GPIOC_BSRR = 0x1000; //Main LED를 켠다. } } return 0; } |

●결과
◉C와 ASSEMBLY 링크
●함수인자 포인터로 받기
- main.c
#include <stdio.h>
void smart(int *);
int main(void) { int iNum = 100;
smart(&iNum);
printf("%d\n", iNum);
return 0; } |
- smart.asm
.386 .MODEL FLAT
PUBLIC _smart
.CODE _smart PROC NEAR32 push ebp mov ebp, esp
mov eax, [ebp + 8] mov DWORD PTR[eax], 777
mov esp, ebp pop ebp ret _smart ENDP
END
|


●함수인자 구조체로 받기
- 어셈블리의 경우 stack이 밑에부터 쌓이므로 인자의 값을 순서대로 넣어야한다.
- 문제 : 다음 구조체 안에 인자 A, B, C, D에 1, 2, 3, 4를 asm를 통해 입력하라.
#include <stdio.h>
typedef struct _common { int A; int B; int C; int D; }common;
void smart(common *);
int main(void) { common obj;
smart(&obj);
printf("A = %d\n", obj.A); printf("B = %d\n", obj.B); printf("C = %d\n", obj.C); printf("D = %d\n", obj.D);
return 0; } |

- 정답 : smart.asm
.386 .MODEL FLAT
PUBLIC _smart
.CODE _smart PROC NEAR32 push ebp mov ebp, esp
mov eax, [ebp + 8] mov DWORD PTR[eax], 1 mov DWORD PTR[eax+4], 2 mov DWORD PTR[eax+8], 3 mov DWORD PTR[eax+12], 4
mov esp, ebp pop ebp ret _smart ENDP
END
|

- 결과


●어셈블리와 변수
- 어셈블리는 변수라는 개념이 없다.
- 우리가 변수라고 생각하는 것이 주어지면 그것만큼의 공간을 확보할 뿐이다.
- 예제


●레지스터 값들 출력하기1
- main.c
#include <stdio.h>
typedef struct _common { unsigned int eax; unsigned int ebx; unsigned int ecx; unsigned int edx; unsigned int esi; unsigned int edi; unsigned int esp; unsigned int eip; unsigned int efl; }common;
void smart(common *);
int main(void) { common obj;
smart(&obj);
printf("eax : [%08x]\n", obj.eax); printf("ebx : [%08x]\n", obj.ebx); printf("ecx : [%08x]\n", obj.ecx); printf("edx : [%08x]\n", obj.edx); printf("esi : [%08x]\n", obj.ecx); printf("edi : [%08x]\n", obj.edx); printf("esp : [%08x]\n", obj.esi); printf("eip : [%08x]\n", obj.edi); printf("efl : [%08x]\n", obj.esp);
return 0; } |
- smart.asm
.386 .MODEL FLAT
PUBLIC _smart
.CODE _smart PROC NEAR32 push ebp mov ebp, esp
mov eax, [ebp + 8] mov DWORD PTR[eax], eax mov DWORD PTR[eax+4], ebx mov DWORD PTR[eax+8], ecx mov DWORD PTR[eax+12], edx mov DWORD PTR[eax+16], esi mov DWORD PTR[eax+20], edi mov DWORD PTR[eax+24], esp
push ebx mov ebx, [ebp+4] mov [eax+28], ebx pop ebx
pushfd push ebx mov ebx, [ebp-4] mov [ebp+32], ebx pop ebx mov esp, ebp pop ebp ret _smart ENDP
END
|

●레지스터 값들 출력하기2
- 어셈블리 함수가 호출되기 직전에 상태의 값을 출력하게 수정하려고 한다.
- eax도 이미 값이 수정 되어버렸다.
- esp의 위치를 조정한다.
- 구조체의 위치를 바꾼다.
- main.c
#include <stdio.h>
typedef struct _common { unsigned int esp; unsigned int eip; unsigned int ebp; unsigned int edi; unsigned int esi; unsigned int edx; unsigned int ecx; unsigned int ebx; unsigned int eax; unsigned int efl; }common;
void smart(common *);
int main(void) { common obj;
smart(&obj);
printf("main : [%08x]\n", main); printf("&obj : [%08x]\n", &obj);
printf("eax : [%08x]\n", obj.eax); printf("ebx : [%08x]\n", obj.ebx); printf("ecx : [%08x]\n", obj.ecx); printf("edx : [%08x]\n", obj.edx); printf("esi : [%08x]\n", obj.esi); printf("edi : [%08x]\n", obj.edi); printf("esp : [%08x]\n", obj.esp); printf("eip : [%08x]\n", obj.eip); printf("efl : [%08x]\n", obj.efl); printf("ebp : [%08x]\n", obj.ebp);
return 0; } |
.386 .MODEL FLAT
PUBLIC _smart
.CODE _smart PROC NEAR32 push ebp mov ebp, esp
mov esp, [ebp+8] ;esp가 eax와 동일하다. add esp, 40 ;변수만큼 내린다. pushfd push eax ;당장 eip를 구하기 까다롭기 push ebx ;때문에 구조체의 순서를 바꾼다. push ecx push edx push esi push edi push [ebp] ;ebp push [ebp+4] ;eip
mov esp, ebp ;해결이 불가하여, 원래의 stack로 돌아온다. push eax mov eax, ebp add eax, 12 mov esp, [ebp+8] mov [esp], eax mov esp, ebp sub esp, 4 pop eax
mov esp, ebp pop ebp ret _smart ENDP
END
|

