(이 포스트는 코드 주석처리가 아직 안되었기 때문에 조만간 주석처리를 할 예정입니다:D)
제가 친구의 요청으로 졸지에 어셈블리 언어(Assembly Language)숙제를 하게 되었습니다.
(제가 다른 교수님 숙제라고 소스 코드를 공개하지만 학과장님 수업 과제였다면 공개를 안했을 것입니다 캬캬)
제가 듣는 학과장님 수업이 아니라 박모교수님이 수업하시는 것 숙제를 해달라는 것이였습니다.
SPARC Architecture, Assembly Language Programming, and C에 있는 연습문제 프로그래밍 해달라는 것이였습니다.
이것이 SUN사의 SPARC Machine에서만 돌아간다는 Assembly 언어 책입니다 -_-;; (책이 딱 한 종류밖에 없더군요)
여기서 다루는 Assembly언어는 SUN사의 SPARC Machine에서 실행되는 Assembly 언어 입니다. 다른 학교에서는 8051 Chip으로 Assembly 언어를 다루는데 .. 저희 과는 특이하게도 SUN사 SPARC Assembly를 다루더군요.
(다음학기때는 전자전기공학부의 마이크로컴퓨터를 배워볼까나? - 어디서든지 많이 쓰는8051Chip에서 쓰는 Assembly를 배운다고 하네요.(선배가 학점따기 쉽다고 해서 들어볼까 생각중))
연습문제 2장 문제
CHAPTER2. SPARC ARCHITECTURE
2.13 Exercises
2-3. Write a program to find the maximum of x³-14x²+56x-64 in the range -2≤x≤-8, by stepping one by one thought the range.
순간 머리가 멈칫... 그리고 어떻게 풀어야 할지 대략 감을 잡았습니다.
C언어라면 금방 짰을 과제인데 =_=
근데 전 단순히 -2부터 8까지 값을 while loop로 돌려 넣어서 값을 찾아내게 했습니다.
-2부터 8까지 값을 loop를 돌리면서 결과값을 Assembly code로 if else로 코드 짜는데
귀찮은것짜증내면서 삽질을 요하게 되고, 레지스터에 써야할 것은 한계가 있는데, 시간이 아깝다는 이유로 -2부터 8까지 값을 loop로 돌려서 결과값을 출력하게 했습니다.
아래 코드는 최대한 최적화를 하게 만들었습니다. 아무짝에 쓸모없는 nop 명령어를 지워버릴려고 얼마나 노력을 많이 했는지 =_=
아래의 같은 코드 파일 :
ex2_3.s
.section ".data"
fmt: .asciz "%d is %d\n"
.section ".text"
.global printf
.global main
main:
save %sp, -96, %sp
mov -2, %l0
.global loop
loop:
cmp %l0, 8
bg done
nop
mov %l0, %o0
call .mul
mov 56, %o1
mov %o0, %l3
mov %l0, %o0
call .mul
mov %l0, %o1
mov %o0, %l1
call .mul
mov 14, %o1
mov %o0, %l4
mov %l1, %o1
call .mul
mov %l0, %o0
mov %o0, %l2
add %l2, %l3, %l1
sub %l1, 64, %l1
sub %l1, %l4, %l1
! output function call!
set fmt, %o0
mov %l0, %o1
call printf
mov %l1, %o2
add %l0, 1, %l0
bl loop
nop
done:
mov 1, %g1
ta 0
자 작업을 다 했으면 컴파일을 해볼까요?
[10/11(수) 03:56 cea5151@sol1] ~/assem/ch2$ gcc -g ex2_3.s -o ex2_3
gcc는 C 컴파일러이지만 어셈블리 언어도 컴파일이 됩니다. :D
-o ex2_3 은 컴파일 한 결과물을 a.out으로 저장하지 말고 ex2_3이란 파일로 저장하라는 말입니다,
-g ex2_3.s 는 ex2_3.s란 어셈블리 언어로 작성된 파일을 컴파일하는데 -g라는 옵션을 붙여서 컴파일 된 후 실행파일이 gdb가 소스 코드를 분석할 수 있게 컴파일을 하라는 것입니다 :D
Solaris에서 작업을 했으면 아래의 에러가 안나고 아주 편하게 컴파일이 될 것입니다. 그러나 윈도우즈에서 작업을 해서 ftp로 올린다면 컴파일이 안된다고 gcc에서 에러를 쏟아냅니다.
[10/11(수) 03:56 cea5151@sol1] ~/assem/ch2$ gcc -g ex2_3.s -o ex2_3
/usr/ccs/bin/as: "ex2_3.s", line 1: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 2: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 3: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 4: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 5: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 6: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 7: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 8: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 9: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 10: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 11: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 12: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 13: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 14: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 15: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 16: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 17: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 18: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 19: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 20: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 21: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 22: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 23: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 24: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 25: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 26: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 27: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 28: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 29: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 30: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 31: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 33: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 34: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 35: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 36: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 37: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 38: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 39: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 40: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 41: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 42: error: invalid character (0x0d)
/usr/ccs/bin/as: "ex2_3.s", line 43: error: invalid character (0x0d)
[10/11(수) 03:56 cea5151@sol1] ~/assem/ch2$
제대로 타이핑을 했는데도 이런 이상한 일이 벌어짐을 알수 있습니다. 이 것은 윈도우즈에서 작업을 했기 때문에 파일 포맷이 windows로 되어 있게 저장된 것입니다. Solaris나 Unix, Linux같은 경우에는 파일 포맷을 UNIX로 쓰기 때문에 이런 결과가 나타나게 되는 것입니다.
이 문제를 해결하는 방법은
[10/11(수) 03:56 cea5151@sol1] ~/assem/ch2$ dos2unix -o -k ex2_3.s ex2_3.s
dos2unix라는 프로그램을 실행시키는 것입니다. 이 명령어는 파일 포맷이 dos인 텍스트 파일을 UNIX 파일 포맷으로 바꿔준다는 말입니다.
man보고 어떻게 실행하는지 알았습니다. 자세한 것은 man 명령어 쳐서 알아보시길 바랍니다 :D
아 컴파일을 해볼까요?
[10/11(수) 03:56 cea5151@sol1] ~/assem/ch2$ gcc -g ex2_3.s -o ex2_3
[10/11(수) 03:56 cea5151@sol1] ~/assem/ch2$
컴파일이 제대로 되었다는 것을 알았습니다.
그러면 실행을 해볼까요?
[10/11(수) 03:56 cea5151@sol1] ~/assem/ch2$ ./ex2_3
-2 is -240
-1 is -135
0 is -64
1 is -21
2 is 0
3 is 5
4 is 0
5 is -9
6 is -16
7 is -15
8 is 0
[10/11(수) 03:56 cea5151@sol1] ~/assem/ch2$
원하는 결과가 나왔습니다.
전 학과장님께서 가르쳐 주신 책에 없는 print 명령어를 써서 결과 값이 제대로 되었는지 알았다만... 박모 교수님 시간에는 숙제를 print 명령어 없이 하라고 했기 때문에... 어떻게 하는지 모르겠습니다.
(gdb를 돌려서 해야하는가?)
이 프로그램을 C로 짠다면...
C언어 Code :
ex2_3.c#include <stdio.h>
main()
{
int temp,i = -2;
while (i <= 8) {
temp = (i*i*i) - (14*i*i) + (56*i) - 64;
printf("%d is %d\n",i, temp);
i++;}
}
결과값은 아까 전의 Assembly code랑 같습니다 =_=
-2 is -240
-1 is -135
0 is -64
1 is -21
2 is 0
3 is 5
4 is 0
5 is -9
6 is -16
7 is -15
8 is 0
이렇게 간단하게 짜집니다 ㅠ_ㅠ
정말 Assembly 언어 공부하면서... C언어가 편하다는 사실을 깨닫게 됩니다 ㅠ_ㅠ