2011년4월25일..NASM, MASM, function복습과 return문, AVR LED응용실습3



  NASM



http://nasm.us 에 접속하면 상단의 메뉴가 보이고,


Documentation을 클릭…


NASM 2.10rc4 온라인 문서를 받는다.
PDF format <- 클릭하면 다운로드되지롱~

알파벳과 숫자와 특수문자들을 조합해서 ‘nasm’이라는 글자를 그래픽으로 표현한 것이 마음에 든다.
외국인들은 이렇게 문자로 그림그리기를 좋아하더라… 왜 그럴까?
아마 실용적인 습관이 아닌가한다…문자로 그림을 표현하면 용량이 확실히 적을 테니…



다음에는 다운로드를 클릭하여…


리눅스FTP(?) 디렉토리들이 보이면,

2.10rc4디렉토리로 들어가서,

dos디렉토리로 또 들어간다…헉헉 힘들다…
아파치 서버구나… 옛날부터 많이 쓰였지..안정성이 뛰어난가?

nasm-2.10rc4-dos.zip을 다운 받자~ 왜? 용량이 많으니까…

뭔가 색깔없는 파일들이 있다…아이콘 좀 만들지…
nasm.exe파일을 C:\windows폴더로 복사하고 실행하면,


어셈블리어 소스파일을 파라메타로 넣지 않았으니 에러가 뜬다.
windows폴더는 환경변수 path에 등록이 되어 있으므로 어떤 폴더에서 실행하더라도 연결이 되는 것이다. 확인!

암흑의 FTP루트를 통해 MASM을 다운 받자…
그냥 구글에서 MASM치면 나오던데..그냥 MASM이 아니라 MASM32다… 뭔가 게임기 비슷하다.

어찌되었든 압축을 풀어보면…

Examples과 Software에 있는 setup.exe를 모두 실행하여 설치하자.

 


이런 메세지가 보이면 당신의 컴퓨터의 windows버전이 높은 것이다.
그럼 어떻게 하느냐? MASM32를 받으면 해결된다.

 

그런데 내 컴퓨터에는 VS2010이 설치되어 있어 그런지 MASM이 설치되어 있다.
그래도 다운 받자!

http://google.co.kr 에서 MASM검색…


도메인네임이 MASM32다!! 멋지군…


용량은 4MBytes도 안 되면서 너무 오래 걸린다. 밑에 시드니 호주를 클릭하니 빨리 되네…호주가 가까워서 그런 것 같다.

어째 파일 하나만 달랑 있는 것이 조금 불안하다…

혹시 있을지 모르는 악성코드가 있나 검사해보자.

다행히 이상은 없다.

아바스트가 괜시리 겂을 준다.
나는 남자다! 화끈하게 다음과 같이,

괜찮아 어차피 데이터 날려도 99%가 야동(야구 동영상)이야…

 

MASM32도 괜시리 겂을 준다.
그나저나 어디서 많이 본 약어가…

설치하려고 실행하였으니 당연히 ’예’를 클릭…




구글의 도움을 받아 번역하니…(OCR유틸 사용해야겠다. 타이핑 힘들었음)
이 설치는 백그라운드에서 OR를 자동 실행하도록 설계되지 않았습니다. 이것은 라이브러리를 빌드하는 프로세서 집약적인 작업을 수행 제대로 작동하지 않거나 실행 무인 경우 혹은 낮은 우선순위로 라이브러리를 빌드합니다.

우선순위와 실행과 빌드이야기가 나오는 것으로 봐선 확인을 클릭해야겠다.

헉! 이건 뭐지?
설치 스크립트인듯한데 비주얼베이직이네… 악성코드는 아닌듯하니…Yes

 

C드라이브에 masm32폴더에 가니 스크립트파일이 있다.
어찌되었든 압축풀기 버튼을 클릭하면 (스샷 못 찍었음)

압축을 풀기 시작하고 많은 폴더와 파일들을 토해낸다.

!#^@$%#@% 무슨 뜻인지 모르겠다….
확인밖에 없어! 누르는 거야!

누르니 열심히 라이브러리들을 생성하고 있다…
그런데 라이브러리들은 오래 전에 만들어진 것들이구나…가면 갈 수록 최신 라이브러리가 생성된다.
생각해보니…ASM소스로 라이브러리를 만들면 용량이 보통 커지자나! SSD용량 얼마 안 남았는데 ㅠㅠ

그런데 설치하다 보니 CM선생님께서 공유하신 MASM이랑 많이 틀린 것 같아!!
선생님껀 컴퓨터구조를 이해하기 위한 예제들이 있는데…MSAM32예제는 달라!

이상한 에러가 뜬다…검색해보니 아이콘지원에 관한 것인데 자바업데이트하면 메세지가 뜨지 않는다고 한다.
살포시 무시해주자…

그런데 설치 파일들을 보니 네트워크관련 어셈블리어파일에서 오디날을 찾네…
어셈블리어로 네트워크 프로그래밍 할 일은 없으므로 무시무시…


너무 파일이 많고 복잡하다…

어라 순서가 뒤죽박죽이네…아래의 화면이 뜨기 전에 한 단계 더 있었구나…
그런데 어베스트가 막는 바람에 실행이 되지 않은 것…

yes를 클릭하면!


MASM SDK에 오신 것을 환영합니다.
빠른 트랙 고성능 소프트웨어 개발. (암튼 좋다는 뜻)

 


기존의 cl의 친구 ml은 어디 있나 환경변수를 확인해 보니 VC의 실행파일에 들어가 있다…
path설정이 되어 있으니 어느 폴더에서든 ml을 실행할 수 있다.

 

MASM32가 좋은 줄 알고 설치했더니…
비주얼스튜디오2010의 ml보다 오래 전에 만들어진 것이다…괜찮아 울지 않아…설치화면 캡쳐를 했으니 수확은 있자나…흑흑
(한 시간 동안 뭘한거지… 멍~)

 

그럼 MASM의 역활은 무엇인가?

컴파일5단계에서 main.i파일이 2단계 컴파일을 거치면 어셈블리 파일 main.s가 생성되고 3단계 어셈블러를 거치면 오브젝트파일인 기계어가 나온다. 이대로는 실행이 불가능하므로 마지막 링크를 거쳐 실행파일이 만들어 진다.
즉, 컴파일 3단계를 담당하는 어셈블러다.
MASM은 마이크로소프트사에서 만들어 windows에서만 되고,
NASM은 linux와 windows 모두 다 된다.
그 외에 GAS라는 GCC가 호출하는 어셈블러도 있다.

 

함수 복습 (임베디드C p.168까지 읽고 질문과 답)

질문준비.printf()에서 정수형 변수를 %f형식지정자로 출력 시 0으로 나오고 자리가 정해진 것과 다르게 나온다. printf() 버그인가?

Q1. 책p.163의 컴파일 결과와 다르게 GCC에선 경고가 뜨지 않고 CL에선 경고가 뜬다.
A1. 컴파일시 –Wall옵션(W는 경고, all은 모든 경고 출력)을 주면 경고가 뜬다.
   CL은 상용이라 사소한 오류도 잡아줘 시스템의 안정성이 높아지게 하나 GCC는 무료라 수준이 떨어지고 경고도 기본적으로 출력하지 않게 되어 있다.

아래와 같이…상용컴파일러인 CL은,

int main()부분
scanf()는 전에 설명했듯이 키보드로부터 입력 받은 문자들이 모니터에 보이니 보안문제가 있다는 경고이다.
19번 행의 avg = average(iNum1, iNum2); 에서 int –> short 대입 시 데이터 손실에 대해 알려줌.

이렇게 모든 경고를 출력 해주는게 좋으나…VS6.0과 달리 VS2010은 아래와 같이,

아무런 경고를 출력하지 않는다.

gcc는 원래 경고를 출력하지 않지만 –Wall옵션을 주면,

21번 행 숫자1과 숫자2의 평균을 출력하는 printf()의 오류를 알려준다.

결론은 CL과 GCC는 서로 다른 곳이 잘 못 되었다고 알려주고,
VS6.0의 경우 모든 경고를 기본적으로 출력하니 개발자에겐 더 좋은 컴파일러라고 할 수 있고,
VS2010의 경우 모든 경고를 기본적으로 출력하지 않으나 현재까지 알려진 많은 문제에 대해 보다 많이 보다 자세히 알려주는 것 같다.

서로 다른 부분이 잘 못 되었다고 알려주는 부분에서 GCC는 printf()의 문제를…
CL은 int –> short대입 시 데이터손실문제를 콕 집어주는데 CL이 더 좋다고 할 수 없는 것이 printf()에서,

정수형 변수를 %f형식지정자로 출력 시 IEEE-754포맷으로 바뀌어 엉뚱한 값(0.00000)이 출력된 다는 것은 쉽게 이해할 수 있으나 3번째 자리가 2번째 자리에 출력되는 것은 잘 이해가 되지 않는다. 내 생각엔 printf()의 버그인 듯 하다. (개발자가 어떤 값을 넣더라도 원만히 처리할 수 있어야 하나 자료형의 문제로 출력위치가 바뀐다는 것은 심각하다)

이런 버그가 있는 함수에 대한 경고 : 더블포맷, 다른 타입 arg (arg2) 를 알려주니 GCC도 무료치곤 좋은 컴파일러다.
CL은 상용이면서 자주 쓰는 이런 printf()에서 오류를 찾아주지 못 하니 반성해야 할 것이다. (MS사)

 

Q2. 책p.167 p6-3.c리턴은 왜 하는지?
A2. 예비군 훈련을 받는 날 수업한 내용이다.


 

함수의 반환 자료형과 return의 자료형이 같아야 한다.
다르면 어떻게 될까? 아직 해보진 않았으나 문법에러가 나진 않고 p6-2.c와 같이 잘리지 않을까 한다.

main()은 프로그램이 시작이니 최초수행 되어 여러 작업을 처리하고 plus()를 호출하면 잠시 main()는 멈추고,
plus()를 수행하여 return을 만나면 plus()에서 main()로 값을 돌려 주게 된다.
즉, plus(27, 24)는 정수 51과 같다.

평소에 쓰던 int main()에 관해...임베디드C p.162
"main() 함수의 경우 반환자료형이 명시되지 않았을 경우 int형으로 간주된다. main()함수는 프로그램의 종료가 정상이면 0을 운영체제에게 돌려주고, 그렇지 않으면 0이외의 값을 돌려준다. 많은 경우...."

정상종료 했다는 것을 운영체제에 알려주기 위해 이 때까지 0을 리턴하였구나!
비정상종료 시 0이외의 값을 돌려준다는데 혹시 쓰레기값인가? 리턴값에 해당하는 메모리가 있을 것인데 초기화를 하지 않으면 쓰레기값이니...

<지역변수>
main()의 result와 plus()의 result는 서로 다른 변수이다.
(검증법은 각 변수의 주소를 출력하여 다르다는 것을 증명하면 된다.)

검증결과 서로 다른 변수임.

 

★p6-2.c의 warning을 없애기 위해 캐스팅하라.

===>

사용자 정의 함수를 수정할 수 있겠으나 보통 피호출함수는 고정해 놓고 main()을 변경한다.
피호출함수는 검증이 완료된 모듈(개념)이기 때문이다. 만약 직상상사가 짜놓은 소스라면 쉽게 변경할 수 있겠는가?

이렇게 캐스팅을 하여도 CL에서만 경고가 사라지지 GCC는 printf()에 관한 오류를 알려준다.

 

나의 Q. p.167 plus()와 minus()의 result주소가 같다. 지역변수라 달라야 하는데 왜 같은지?
          (후에 알아보니 인자 first, second도 주소가 같았다.)

A. 그건 나중에….



 

Q. p.163 main()의 마지막행에 정수를 %f형식지정자로 출력시 이상한 값출력.
A. IEEE-754방식으로 보기 때문에 이상한 값이 출력된다.
옳게 출력하려면,
float A = num1;
실수형변수에 정수를 대입하여 출력.
(경고도 뜨지 않고 원하는 결과를 얻었다)

 

 

함수의 return문 (p6-4.c)

 

getnum()의 scanf()에서 아무리 큰 값을 입력하더라도 양수의 최대값이상으로 들어가지 않음.
scanf()의 %d형식지정자의 특징인듯함.

★지역변수는 함수가 종료될 때 소멸된다.
  예제6-3에서 지역변수의 주소가 같은 이유는 함수가 호출되고 메모리(변수)를 할당받아 사용하고 종료될 때..
 그 메모리를 다른 함수나 프로그램에서 사용할 수 있도록 되어 있는 것이 아닌가 한다.

시간  명령(문법X)  main :: num  getnum :: num   checknum :: n   설명
 1  num = getnum();  ?  ?   초기화되기 전 
 2  scanf() num = 7;  ?  7   키보드로 부터 7받음
 3  return 7;  7   소멸   7을 리턴, 지역변수 소멸
 4  num = checknum(num); return n;  7   소멸  
 5  num갯수만큼 *출력  7  소멸   소멸   


 티스토리 표에 아직 익숙하지 않아서 그런지 보기 흉하네.;;






LED응용실습2-2 풀이

스위치1 누름   1111 1110
스위치3 누름 &1111 1011
원하는 결과     1111 1010    -> LED출력


스위치입력을 저장할 공간이 필요하다.


if(PORTF == 0x00)
{
    delay();
    PORTF = 0xFF;
}
PORTF = PORTF & PINC;

 

비트연산자

& (AND) – 각 비트를 AND연산. 다항.
| (OR) – 각 비트를 OR연산. 다항
~ (NOT) – 각 비트를 NOT연산. 단항. 1의 보수를 취한다와 같음.
^ (XOR) – 각 비트를 XOR연산.

<시프트>
<< (좌측으로 시프트)
>> (우측으로 시프트)

1Byte 자료와 시프트 연산자 도식과 설명 추가할 것.

 

자주 쓰는 시간지연 부분을 delay()로 만들자

상기의 스크린샷과 같이 두 가지 다른 코드의 함수가 있다.
인라인 어셈블은 아직 배우지 않았으므로 오른쪽과 같이 시간지연 함수를 만들어야 하나 예전에 쓰던 함수라 그대로 불러왔다!
이번에는 전과 다르게 main.c에 포함시키지 않고 분할 컴파일을 해보기로 한다.

delay.c로 저장한 다음 프로토 타입을,

delay.h에 써넣는다.

> avr-gcc –c –mmcu=atmega128 delay.c
도스 프롬프트상에서 라고 입력하면 delay.o파일이 만들어 진다.
파일이 하나 뿐이라 library를 만들긴 부족해 보이니 Makefile을 수정하여 delay.o를 같이 링크하도록 한다.

 

 

 

 

LED응용실습3

1.255에서 부터 0까지 감소하는 숫자를 LED로 표시하라.

(설명)

(동영상)

 

 

 

 


2.LED를 오른쪽에서 왼쪽으로 한 칸씩 이동시키다가 스위치를 누르면 누른 순간의 LED위치에서 반대쪽으로 이동..이동하다 다시 스위치를 누르면 그 LED위치에서 오른쪽에서 왼쪽으로 이동.

 

(설명)

 

(동영상)