『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 424번 제 목:[강좌] 어셈초보 -세그먼트 1- 올린이:nowngm (게임제작) 97/11/27 14:53 읽음:986 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 43번 제 목 : [강좌] 어셈초보 -세그먼트 1- 아주아주기초 올린이 : timebomb(이시원 ) 95/12/07 06:18 읽음 : 1090 관련자료 없음 ----------------------------------------------------------------------------- 안녕하세요.. 아이디 기생하고 있는 송균상이라는 사람입니다.. 나이는 23이구요. 직업은 없어요. 결국 백수라는 얘기겠지요? 게제포의 준회원으로써 이제부터 본격적인 활동을 위해 노력을 하려고 하는 사람이어요.. 저같은 초보가 무슨 강좌냐 하면서 면박을 주실진 모르지만. 그래도 나의 강의를 보고 "아하!" 란 말을 해주는 사람이 한 사람이라도 있다면 전 더이상 바랄게 없습니다. 이상 삼천포는 각설 하구요.. ----------------------------------------------------------- 제가 강좌를 시작하려는 이유는 대충 이렇습니다. 고등학교 2학년때 전 컴을 만지면서 C 란 언어를 책을 보면서 공부하는 도중, 어셈이라는 언어를 이름만 들었어요. 아하..그래서 전 'C 보다는 어셈이 더 강력하겠지' 하면서 서점으로 달려가 어셈블리 초보를 위한 책을 한권 샀죠.. 아니 근디 글씨 이게 웬일이래요. 이게 초보를 위한 책이여?... 할수 밖에 없었죠... 그당시 전 C 도 제대로 못한 인물이었기에 당연한 현상일런지도 모르지요... 아무리 눈ʼn찾아봐도 다른 언어를 모르고서 그리고 컴퓨터의 전반적인 지식이 약한 상태에서는 전혀 진도를 나갈수가 있는 책이 안보이더란 말씀입니다... 각설하고 이 강좌는 아주 초보적인 ( 왜냐?..내가 초보거든..) 컴퓨터 프로그래밍을 위한 제반 지식과 어셈을 하기위한 초보적인 아주아주 초보적인 것을 아주쉽게 아주아주 쉽게 설명하기 위한 노력을 할 것입니다.... 노력만큼 될런지는 저도 여러분도 의문일 것입니다..히이... -------------------------------------------------------------- =========================== 첫번째 주제 : 세그먼트 =========================== 프롤로그 ------------- 어셈 책을 무려 7권 그것도 초보책만 구입하고서 관련분야를 뒤져가면서 이해를 할려고 무진장 노력을 했건만.... 이놈의 세그먼트란 놈을 이해하기가 무진장 어려웠답니다.. 그런데 이놈의 세그먼트란 놈을 이해하지 않고서는 진도를 나가도 이해가 영 시원찮음을 느껴 보셨을런지요.. 사전을 찾아봅시다.. segment : any of the parts into which something may be cut or divided. 해석해볼깝쇼?... 잘리거나 나뉠수 있는 어떤 부분들... 이라고 나왔네요.... 해석이 맞나? 근디 여기서 부터 세그먼트란 단어를 싸악 잊어버리시고 제 말좀 들어보세요......말 나갑니다.... 처음에 퍼스날 컴퓨러가 나왔을 당시 아주아주 획기적인 8비트 컴퓨터가 나왔었데요.. 8비트 컴퓨터에 대해선 저두 잘 모르지만서두 아마두 메모리가 무척 컸(?)데요... 64kb 래지 아마? ( 요부분은 틀렸으면 가차없이 메일 주세요.....) 64키로바이트면 얼마나 ┛け.. 64 곱하기 1024 하면 몇이죠? 어쨌든 8비트 컴퓨러에선 8비트 선 두개를 가지고 64키로바이트를 모두 엑세스(끄집어내고 집어넣기)를 할수가 있었나 보데요........? 요부분 정확히 이해를 하셔야 합니다.......... 좀더 쉽게 설명해 달라굽쇼? 그러지뭐...재가 힘이 있겠습니까............ 우리가 컴퓨러를 만지는 입장에 서지 마시고 우리가 컴퓨러가 됐다 라고 생각 하십시오.... 자아 내가 컴인디 이 명령을 수행해야돼... 메모리에 있는 어떤 값을 가져와서는 쩌어기 메모리의 다른 곳에다가 똑같은 값을 집어넣어야해... 근디 그 어떤 값이 어딨는지를 알아야 뭘 할것 아니냐고요?.....그쵸? 어딨냐?.... 그걸 알기위해서 우린 주소란 말을 사용해요 영어로 어드레스 .....오케이? 근디 이해가 어려운 점 중에 하나가 컴퓨터 주소를 표현 할 시에는 요상히도 꼭 16진수를 사용하드라 그거요.. 기분 나뻐요... 왜냐?... 보통 우리가 사용하는 10진수보다 이해가 어렵거든요..... 하지만 어쩔수가 없어요.... 왜냐?...컴퓨터는 2진수밖에 처리를 못하거든요.... 어어....이해가 더 어려워요....왜죠? 컴퓨터가 2진수를 사용하는디 10진수는 안돼고 왜 16진수는 돼냔 말이야...... 요걸 알아야죠..... 한비트가(1비트가) 표현할수가 있는 정보는 몇개죠? 0,1 두개죠? 그럼 2비트는? 00,01,10,11 네개네..... 그럼 4비트는? 0000,0001,0010,..,1111 열여섯개네요 비트가 4개가 모이면 십육진수로 나타낼수가 있다는걸 이해 하시겠나요?... 찬찬히 생각해보세요.... 그래서 16진수는 0,1,2,3,4,5,6,7,8,9,A,B,C,D,F 이렇게 16개로 표현 합니다 F 가 2진수 1111 과 대응 돼는 거죠.... 실제로 컴퓨터는 2진수로만 알아듣습니다..... 단지 우리가 수를 표현할시에 16진수가 더 편하기 때문이죠 왜냐고요?...왜 더 편하냐고요?.......이런.... 그럼 11111111 이 편합니까 FF 가 편합니까.?...... 질문이 멈췄네......헤에...... 컴이 한번에 알아들을 수 있는 정보를 가지고 몇비트 컴이다란 말들을 합니다..... 즉 8비트 컴퓨터에서 8비트의 한계를 넘어가는 숫자가 나오면 컴이 대번에 들어먹지를 않아요 이건 다른 명령을 더욱 추가해야 합니다....대번에 들은수 있는 수는 0부터 255 까지만 알아들어요 멍청하지 않습니까........? 여기서 255가 FF 란걸 아실랑가요.......? 그럼 주소를 컴이 알아먹기 위해 8비트의 데이타가 두개가 와야하네요? 자아... 8 플러스 8 은 ?......16이죠? 그럼 16비트가 표현 가능한 정보의 양은? 네에....64KB 정답이에요.... 왜냐구요?....아아.....계산 하세요... 자아....여기까지가 8비트 컴에 대해서 그리구 메모리를 표현하는 방법에 대해서 였어요..... 자아....예제를 통해서 확실한 이해를 도웁시다... 메모리 주소(번지) 3F1D에서 숫자를 끄집어 내란 명령을 받았다고 칩시다..... 그럼 그 주소를 전해 받기위해 8비트데이타 두개를 받아들입니다....바로 3F 와 1D 이죠.....흐흐.... 자아 여기까지 ... 솔직히 말해 요 8비트 컴에 대해선 전혀 아는 바가 없어요.... 저의 말이 틀릴 여지가 충분하고도 남습니다... 근디 왜 정확하지도 않는 정보를 이렇게 남발하냐구요? 왜냐면 어디까지나 세그먼트란 놈을 이해하기 위한 방편이지요... 미들로그 (프롤로그 에필로그의 중간(?)) -------------- 자아 이제 시대를 좀 땡깁시다 8비트 컴은 사장된지가 꽤 오래됐죠? 일부 게임기에선 아주 완벽하게 쓰이고 있단 말은 들었어요..히이 그런데 16비트 컴퓨러 즉 XT 와 AT 중에서 286기종이 바로 16비트 였던 거여요..... 자아....아까 8비트 컴에선 8비트 두개를 모아서 메모리를 제어 했지 않았습니까.... 근디 64KB의 메모리는 16비트에선 16비트 하나면 충분하네요...그쵸? 근디 이게 어찌 ┛일입니까.... 64KB 의 메모리가 엄청나게 많은 줄 알았더니.... 모자르더라 이말입니다... 그래서 1MB 로 늘렸어요...... 자아 1MB의 주소를 지정하기 위해선 몇 비트가 필요 할까요 정확히 20비트입니다.... (1024KB 가 1MB 입니다) 어라? 16비트 컴퓨터에서 어쩔수가 없이 두개의 16비트를 사용해야 돼더라 이말입니다... 허어 이게 웬 날벼락이래요...... 여기서 인텔이 그랬는지 마이크로 소프트인지는 몰라도 이놈들이 편법을 그럴싸하게 썼어요....( 인텔일껄? ) 이제부터 너무너무 중요하니까 ...정신집중... 자아 1MB 는 대체 64KB 의 몇배정도나 ┛け楮... 정확히 16배 입니다...... 계산이 돼십니까..? 우선 위로 쭈욱 올라가셔서 세그먼트의 뜻을 다시한번 보세요 이제부터 인텔의 편법 세그먼트가 나옵니다... 나눕시다..!!!!!!!!! 뭘 ??????? 메모리를 !!!! 어떠케? 16바이트씩 나눠버리자구요 16개의 주소를 하나로 깡그리 묶어서 나누는 거예요.. 그게 세그먼트에요.....그게 다예요.... 더이상의 말은 필요조차 없어요...... 결국 1MB 에서 세그먼트는 몇개죠....? 64KB 개에요..... 갯수가 "64 곱하기 1024" 에요.... "아니요..전 그건 알아요....아니 근데..이럴 필요가 있습니까? 그냥 주소를 표현한는데 20비트가 필요하면 16비트 하나쓰고 그다음 16비트중에서 4비트만 써서 하면 돼지........ 책에선 이렇게.......뭐더라...음.....그러니까............. 세그먼트에서 한칸 옆으로 밀고 오프셋에 더하면... 물리적인 주소를 계산 할수가 있다느니 뭐 그렇게 할 필요가 있습니까?" 거참 성급하기도 하시지.... 이제 나옵니다.... 이분이 질문하신것처럼(물론 접니다) 해도 별 문제는 일어나지 않습니다. 잘 보세요.... 세그먼트가 몇개?..64KB 개,...16비트로 세그먼트 표현가능?....오케이 그다음 16비트는 뭘 표현 하냐구요?...바로 그 세그먼트에서 떨어져 있는 거리를 표현 합니다..... 자아....봅시다.... 세그먼트가 D014 입니다.... 다른 16비트(이걸 옵셋이라고 합니다.)는 321C 라고 해두죠.... 그럼 진짜 주소는 어딜깝쇼? 세그먼트가 16바이트씩 하나로 묵어서 정해놨으니 밑을 보시죠 D014 + 321C 이 공식이 왜 만들어질까 고민할 필요가 전혀 ------- 없습니다.....힌트는 세그먼트는 16바이트씩 묶어 D335C 논 것이고 옵셋은 그 세그먼트서부터의 거리를 의미 한다는 것만 염두하시고 찬찬히 생각해보세요.. 에필로그 --------------- " 여보슈...왜 내 말은 대답을 안해주슈....." 아참 제가 깜빡 했습니다... 죄송.....히이 뭘 물어보셨죠?....아아....이해는 했는디 왜 굳이 그렇게 하냔 말이죠? 결론부터 말쌈 올리면 이유인 즉 , 프로그램을 짧게하고 빠르게 실행시키기 위해서 입니다.... "아니 그럼 내 방법으로 하면 프로그램이 길어지고 느리게 실행┛┫말이요?" 대답은 그렇소이다 입니다....... 이유도 알려줄깝쇼? 요건 다음에 하죠....휘이이잉....... 잡담 -------------- 우리나라 프로그램의 현주소를 살펴봅세요.... 아주아주 빠른 진보와 변화를 보이고 있사와요.... 누구도 부인하지는 못하리라 보이지요? 전 의견이 쪼까 달르시와요....... 왜냐굽쇼? 요즘 비주얼 프로그래밍이 한참 붐을 일으키고 윈도즈 프로그래밍을 해야하느니 어쩌느니 이런 얼토당토않는 아주 개차반 같은 말이 들리는데.....나 이거 못 참아요....왜냐굽쇼? 나 이런 그 이유를 몰르다니 이게 말이 ┛눴劉 우린 그 프로그래밍언어를 사용하는 유저차원에서 결코 머물러선 절대로 안┛눼求...아주아주 나아쁜 짓입니다.. 비주얼하게 프로그래밍을 하는 기법을 알아내고 윈도즈 내부 커널이 어더렇게 돌아가는지를 해킹을 해야합니다.... 물론 유닉스나 오에스투 도스등도 마찬가지루 말이죠... 왜 자꾸 이런 말을 하냐구요.... 이 말에 분명히 반대하시는 분도 있으실 걸로 전 믿습니다. 하지만 굳이 이런 말을 하는 이유는 여기에 있습니다.. 더이상 우린 외국프로그램에 의존해서는 안┛눼求... 앞서 가야합니다.... 앞서 가기 위해선 그놈들껄 사용하는데에 그쳐선 안┛눼求 철저히 알아서 자기껄루 소화를 시켜서 더 좋은 놈을 만들어야 합니다 난 우리나라 사람들의 좋은 머리를 특히나 믿습니다.... 왠지 꿈이 없는 젊은이들이 갈수록 많아지는 것 같은 이 세상에서 자신의 꿈을 펼쳐 보이십시다...... 게제포 화이팅 ~~~~!!!!! 여수 똘마니 송균상 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 425번 제 목:[강좌] 어셈초보 -세그먼트 2- 올린이:nowngm (게임제작) 97/11/27 14:55 읽음:669 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 44번 제 목 : [강좌] 어셈초보 -세그먼트 2- 올린이 : timebomb(이시원 ) 95/12/08 19:02 읽음 : 727 관련자료 없음 ----------------------------------------------------------------------------- 안녕하세요... 아이디 기생 송균상 인사 또 올리네요.... 하루동안 무려 여섯분이나 저의 글을 읽어 주시다니 영광에 몸둘바를 모르겠사와요.....지금 시각 새벽 5시....후후 ------------------------------------------------------ ============ 세그먼트 2 ============ 어제 설명한 저의 세그먼트에 대한 얘기 잘 이해가 돼십니껴? 그냥 막 읽어 내려 가시다가 이해가 안오는 부분 체크하시면서 보세요.. 하두번 읽다가 보면.... "아하!!" 하실겁니다.. 저번 강의에서 "아하!!" 소릴 못지르셨을 분들을 위해 오늘 이렇게 세그먼트 두번째를 시작합니다.... 왜이렇게 나눠서 심각하면서도 깊이 하느냐고요? 왜냐. 중요하니깐드루.... 논리적과 물리적 ?? -------------------- 영어에 뉘앙스(풍기는 의미)란 걸 아시는지 모르겠습니다만, 언어가 다른데 이놈의 해석이란거 정말 어렵군요... 왜 이런말을 하냐고요? 이제부터 논리적인 세그먼트와 물리적인 세그먼트를 설명하는데... 이놈의 논리적 물리적이란 말이 별로 맘에 들지 않아서요 자아...저번처럼 자기자신이 컴퓨터가 됐다라고 생각하십시오. 이번엔 자신이 16비트 컴퓨터입니다.... 쩌어기 있는 데이타를 가져와서는 요기에다가 더해라... 란 명령을 받았어여.... 데이타를 가져오기 위해서 그 데이타가 있는 주소를 알아야 하죠? 1MB 를 제어(꺼내기 넣기) 하기 위해서는 20비트의 주소가 있어야 가능합니다.... 그럼 처음 4비트를 먼저 받습니다.....(16비트에서 밑의 4비트만 써서)... 그리고는 16비트를 받습니다.... 이렇게 하면 돼겠죠? 근디 이렇게 안합니다......어떠케 하느냐.... 16비트 세그먼트를 받아요.... 그 다음엔 그 세그먼트에서 얼마나 떨어져 있나 하는 옵셋, 16비트를 받아요........ 이상하다......왜 이렇게 하나.....왜 그럴깝쇼? 위의 예에서 전자를 물리적, 후자를 논리적이라고 해요.... '물리적'이란 말을 '진짜'란 말로 바꿉시다.... 진짜주소는 원래 1MB 를 제어하는 20비트를 의미합니다.. '논리적'이란 말을 '만든'이란 말로 바꾸어버려요... 만든주소(임의적으로)는 32비트(16비트 두개)로 20비트주소를 하려다 보니 생겨난 세그먼트와 옵셋의 개념입니다... 우린 프로그래밍을 할때... 만든주소, 즉 논리적인 주소를 사용합니다... 만든주소를 진짜주소로 바꾸는 것은 우리가 하는 일이 아니고 CPU 가 합니다.... 결국 CPU 에 명령을 내릴때 요 만든주소로 명령을 해야 한다는 말이죠.... 영어로 physical 과 logical 을 각각 물리와 논리로 해석합니다. 그런데 영어권 사람들이 physical logical 하면 어느정도 의미가 와 닿습니다... 그런데 우리나라 보통인간들이 물리 논리라고 하면 와 닿습니까?.....얼토당토 않는 말씀... 이런건 제발 바뀌었으면 하는 바램을 가져봅니다..... 차라리 '진짜' '만든' 이란 것이 팍팍 오지 않습니까? CS,DS,SS,ES -------------- 여태 궁금증은 가시지 않습니다.... 뭐때메?....왜 만든주소를 사용하는지 모르겠어....그치? 우리가 컴에게 명령을 내릴때 어느주소에 있는 데이타를 사용하라고 명령할때 만든주소를 사용하자나요? 만든주소가 뭐에요?.....아네...그렇습니다... 세그먼트와 옵셋....그렇죠? 근디 여기서 우린 옵셋만 컴에게 줍니다.... 세그먼트는 안주냐고요? 세그먼트는 쩌어기 위에 써져 있는 CS,DS,SS,ES 라는 16비트짜리 레지스터에게 줍니다..... 레지스터가 뭔지는 담에 알아봅시다.... 근데 세그먼트는 한번만 저기 레지스터에 저장해주고 고 세그먼트로부터 64KB 까지의 데이타는 옵셋, 즉 16비트만 CPU에 보내주면...CPU 가 알아서 레지스터와 들어온 옵셋16비트를 조합해서 진짜주소를 계산한뒤 값을 읽어들이거나 씁니다. 여기서 이 CS,DS,SS,ES 를 바로 우린 세그먼트 레지스터라고 부릅니다..... DS 란 곳에 A013 이 들어있었다고 가정합시다.... 이때 진짜주소 A0453(20비트=1MB)에 있는 값을 어떤 곳으로 이동하는 명령이 주어져있다고 합시다.. 실제 명령의 형태 : MOV ??,[0323] ?? 란곳에 0323을 옵셋으로 하는 데이타를 카피한단 말입니다. MOV 는 MOVE(이동하다)의 약자이구요... 세그먼트 A013에 해당하는 실제적인 진짜 주소는? A0130 입니다....왜냐고요? 세그먼트의 계념인 1MB를 16바이트씩 나누었으니까요... 계산 해 보세요...... 그리고는 진짜주소 A0130 으로부터 0323 만큼 떨어진곳 플러스 하면 A0130 + 0323 = A0453 이 돼는거죠..... 결국 컴에 입장에 서서 다시한번 생각을 해보죠 옮겨라!!.. ??에다가 ...0323에 있는 값을....... 그럼 우선 DS에 있는 값을 읽어서(A013) 16을 곱합니다....그러면 A0130 돼죠? 여기다가 0323을 더합니다.... 그러면 A0453 , 결국 이 주소에 있는 값을 가져옵니다. 이해가 오나요? 이 작동은 컴이 다 알아서 해줍니다... 만약에 우리가 어떤 값이 현재의 세그먼트 레지스터에 있고 어떤 옵셋(옵셋의 범위는 64KB ,즉 16비트)의 값을 최대한 크게(FFFF) 잡아줘도 원하는 곳을 지정할수가 없는경우 또 옵셋을 아무리 작게(0000) 잡아줘도 그럴경우.... 우린 세그먼트 레지스터에 값을 변경시켜서 해야 합니다.. "저기요... 저 질문이 있는데요.... 그럼 말이죠.. DS 에 A000 있고 옵셋 0100에 있는 값하고 DS 가 A010 이고 옵셋이 0000 일경우의 값하고 같자나요.." 네에....아주 좋은 질문이네요.... 질문이 조금 이상하네요....왜냐하면.....값만 같은게 아닙니다. 값이야.....당연히 같습니다...왜냐하면...저기의 두 논리적, 즉 만든주소는 진짜주소가 똑같습니다.... 물리적인 주소가 같단 말이죠...... 만든(논리적)주소를 만든 이유는 아주 간단하고도 명료합니다.. 우리가 컴에게 명령을 내릴때 옵셋만 주어서 결과적으로 프로그램 수행속도도 빨라지고 프로그램 길이도 짧아지는....... 일석이조요..금상첨화요..담배자판기에서 하나 뽑았는디 두개가 나오는 격이죠.....흐흐...... 이제야 세그먼트의 기초적인 이해가 어느정도 마무리 된거 같군요..... 근데 궁금한거 없습니까? 나같으면... CS,DS,SS,ES 가 뭐하러 이렇게 많이 필요한가...어떤이유로 쓰이는걸까? 하는거죠 다음번엔 레지스터란 것에 논할것입니다... 이 레지스터란 놈을 배우면 이 질문이 쏘옥 들어갈껍니다.. 오늘의 강의 이걸로 끄읕 !!! 아직도 세그먼트에 대해 이해가 오지 않습니까? 어쩌나...난 아주 쉽게 설명할려고 애를 썼는디.. 앞으로도 그럴껍니다... 어렵지만 깊은 공부는 이해를 최고조로 만든다는 논리에 입각, 우리모두 어셈을 배웁시다... 담에 또 봐용....또 오세요....~~~~~~~~~~~ 여수 똘마니 송균상 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 426번 제 목:[강좌] 어셈초보 -레지스터- 올린이:nowngm (게임제작) 97/11/27 14:57 읽음:662 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 45번 제 목 : [강좌] 어셈초보 -레지스터- 올린이 : timebomb(이시원 ) 95/12/09 02:01 읽음 : 705 관련자료 없음 ----------------------------------------------------------------------------- 안냐세요.... 어셈을 배우고픈 사람이 이렇게 없었나요...? 아니면 다 아는 얘기를 괜시리 해서 인기가 없나. 음....어쨌든 전 계속 할랍니다. 이 강좌는 제가 어셈을 배우면서 너무나도 이해가 힘들었던 부분들로 채워갈 생각입니다. 책을보며 이부분이 너무 이해가 힘들어요 하신분이 계시면 가차없이 메일을 보내 주세요...히히.. 오늘의 강좌는 레지스터입니다... ====================== 오늘의 주제 - 레지스터 ====================== Register : 저장소라고 생각하십시오. 메모리도 정보 저장소 아닙니까?....당연하지요... 그럼 레지스터도 저장소에요?......그렇습니다.. 뭐가 틀려요? 뭐가 틀릴까.... 우선 뭐가 같은가 부터 봅시다... 데이타를 읽고 쓸수 있는 곳이란 것이 같아요.... 지우고 쓰고 지우고 쓰고 할수가 있지요.... 틀린점은 대충 이정도면 아하!! 하실겁니다... 우선 매체(뭘로 만들었냐)가 다릅니다... 레지스터는 s-ram 이란걸루 만들었고 메모리는 d-ram 이란걸루 만들었다고 하네요... 틀리면 가차없이 메일 주세요... 레지스터가 훨씬 쓰고 지우고 하는데 있어서 빠릅니다. 그래서 가격이 비싸요.... 메모리는 그에 비해 느립니다...그리고 싸죠... 그리고 단적으로 다른점이 있습니다.... 레지스터는 기껏해야 몇십개 밖에 없고 메모리는 확장도 가능하고 엄청난 용량입니다... 또 한가지 어셈에 있어서 중요한 차이점이 있습니다.. 레지스터는 각각 고유의 이름(?)이 붙어 있습니다.. 메모리는 주소가 이름이지요.... 또 있어요... 레지스터는 대부분 그 레지스터가 주로 뭘 할때 사용되는가 하는것이 정해져 있습니다.... 물론 안 그런것도 있어요.... 단적으로 아주 중요한 레지스터의 일반적인 공통된 쓰임새와 레지스터가 있는 이유가 있습니다... 레지스터가 왜 필요하지? 빠르니까?...물론 이유가 되긴하네... 하지만 더 중요한 이유가 있습니다... 우리가 컴퓨터라고 가정하고 프로그램을 실행한다고 봅시다. 어느곳에서 데이타를 읽어서 그걸 덧셈을 한다고 보자구요. 데이타를 읽었다. 요걸 어디다 놓고 계산을 하지? 에이 우선 여기다 놓고 계산 하자... 바로 여기가 레지스터 입니다... 어셈을 하는데 있어서 레지스터의 천재적인 사용은 프로그램의 수행속도를 몇배에서 수십,수천(?)배를 올릴 수 있습니다... 잘못 사용하면 또한 프로그램이 더더욱 길어지고 멍청해지는 경우도 있습니다... 레지스터의 이해와 적당하고도 천재적인 사용은 어셈프로그래밍의 기초이자 제일 어려운(?) 부분이고 여기서 프로그래밍 실력이 차이가 납니다... 너무 겁은 먹지 마세요... 왜냐구요?...기초니까... 왜 이런 현상이 생기냐 하면요.... 레지스터는 갯수에 제한이 있고, 사용방법이 조금 까다로워요 16비트(특히 XT)의 레지스터가 무엇이 있나 봅시다... AX,BX,CX,DX,CS,DS,SS,ES,SI,DI,BP,SP,IP,FLAG 10진수로 0 에서부터 65535 까지의 데이타를 저장할수 있는 16비트 레지스터의 전부일껄요.. 또 있나...? 종류별로 나누어봅세요... 범용(제너럴,보통,자주사용하는) 레지스터는 AX,BX,CX,DX 여태 배웠던 세그먼트를 저장하는 레지스터는 CS,DS,SS,ES 또 옵셋을 주로 저장하는 레지스터는 SI,DI,BP,SP,IP 그다음엔 플레그(상태)를 저장하는 FLAG 이렇게 4가지의 종류로 나눌 수가 있습니다.. 이제부터는 아주 중요합니다...주목하십시오... 세그먼트레지스터와 옵셋을 저장하는레지스터는 주로 쌍으로 상호작용을 한다구 하드만요... 당연하지 않습니까?...여태 배웠지 않습니까... 유추해 볼수 있겠죠?.....모르겠다구요?...이런.. 그럼 앞의 강좌를 복습하세요... CS 와 IP 가 둘이 잉꼬부부랍니다... SS 의 부인은 SP 입니다...근디 첩도 있네요...BP DS 와 ES 는 각각 DI SI 와 애인사이라고 하네요.. 애인사이라 그런지 외도(?)를 자주 합니다... AX,BX,CX,DX는 각기 특성을 가진 싱글(?)입니다.. FLAG는 이 레지스터 마을에 봉화대 깃발맨(?)입니다...히히 CS 와 IP 는 정말로 친한 잉꼬부부입니다.. 두 부부가 하는 일은 단 한가지 입니다.... 지금 프로그램이 어디까지 실행이 되고 있는가 하는 주소를 저장하고 있습니다.. CS 의 부인인 IP 는 절대 건드리지 맙시다... 컴퓨터가 절대 가만두지 않습니다.. 섣불리 꼬셨(엑세스)다가는 큰코를 다치죠....흐흐... SS 는 부인과 첩을 둔 아주 능력(?)있는 놈이네요... 부인인 SP 와는 스택이라고 하는 아주 복잡하고 강력한 구조를 형성합니다..( 다음주제가 바로 스택인 만큼 쉽진 않죠.) 요 부인도 아주 강직한 성품이라서 함부로 스택구조를 건드리면 엄청난 화를 자초하게 됩니다.... 대신 저기 잉꼬부부와는 달리 첩이 있어서... 그 첩을 꼬시면 만사 오케이 물론 잘 꼬셔야 합니다.. DS DI 와 ES SI 는 서로들 애인사이라면서 잘들 사귑니다만 얘들 꼬시는건 식은죽 먹기 입니다... 레지스터의 정보담당관들로써 어떤 주소에 어떤 정보를 서로 주거니 받거니 하거나 컴에게 정보들을 넘겨주는 아주 요긴한 놈들입니다... AX,BX,CX,DX 는 아주 친한 친구사이들인데 서로 협력해서 아주 다방면에서 일을 하는 쫄병들입니다.. 먹여살릴 처자식(?)이 없어서인지 하는 일이 자주 바뀌구요. 4명이 협력해서 숫자계산(가감승제)에 아주 능하고요. AX 와 DX 가 협력해서 메모리가 아닌 다른놈들(IO:사운드카드나 비디오카드,프린터 여타 다른 외부장치들)과의 교신을 합니다. 또한 카운터라는 별명을 가진 CX 또한 별명다운 일을 합니다. BX는 가만히 있진 않겠죠? 요놈두 일반 씨에서 말하는 배열(어레이)와 관계되는 아주 중요한 일을 합니다... FLAG는 봉화대 깃발맨으로써 가끔씩 여러가지 깃발들(아주 중요한 정보)을 가지고 여기저기 명령도 내리고 정보도 전달합니다... 진짜 여러가지의 깃발들이 있어서 눈에는 보이지 않는 아주 중요한 역할을 담당합니다... 여기까지 우리가 주로 사용하고 알아야 하는 레지스터에 대해서 간략하게 나마 썼어요... 아니 그럼 레지스터가 또 있어요?..라고 말하시나요? 네에...그렇습니다.. 386,486기종에서는 더욱 확장된 레지스터들이 존재합니다. 그러나 아직은 이 레지스터만 알아도 충분!~~~ 이 레지스터들의 쓰임새는 내가 여기서 주저리 논해봤자.. 택도 없습니다.. 명령어와 함께 해야 이해가 팍팍 오거든요.. 그래서 레지스터는 감히 여기까지만 함을 용서하세요 제가 레지스터 나라가 어쩌구 그러면서 한 위의 얘기를 다시금 뇌리에 스쳐지나가면서 기억해보려 노력해보세요.. 나중에 명령어와 함께 해나가면 이해가 팍팍 옵니다... 그럼 다다음 주제에선 명령어와 함께 레지스터들을 꼬셔(?)볼께요 다음 주제는 미리 말씀 드립니다... 바로 스택이란 놈입니다.... 한가지만 알려드리죠....스택을 가장 가깝게 번역하자면...선반(?) 이라고 감히 말씀 드립니다... 정보를 저장하는 선반.... 그럼 이만... 여수 똘마니 송균상 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 427번 제 목:[강좌] 어셈초보 -스택- 올린이:nowngm (게임제작) 97/11/27 15:03 읽음:633 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 46번 제 목 : [강좌] 어셈초보 -스택- 올린이 : timebomb(이시원 ) 95/12/11 00:17 읽음 : 686 관련자료 없음 ----------------------------------------------------------------------------- 안냐세요... 정말 재수없는 일이 생기고 말았습니다... 저의 전번 3개의 chapter 의 강좌가 그만 내 하드에서 날라가 버렸습니다. 내가 쓴글을 내가 받아가야 하는 불상사가 생기다니. 흐흐.. 어쨌든 여태까지의 강좌를 몇분(?)이나마 즐거이 읽어 주신걸 감사 드립니다... 자아....이제부턴 뭐랄까... 정말 혁신적이고도 조금은 어려운 듯한 스택에 대하여 말쌈 드리고 싶습니다.. 프로그램을 짜는데에 있어서.. 아니.. 컴퓨터에 어떤 명령을 내리는 데에 있어서 정말 고급스러운 기법이 바로 스택입니다. 이 구조를 도입하므로써 우린 적은 수의 레지스터로도 부드러운 알고리즘(명령의 나열(?))을 만들 수가 있으며, 또한 보기에 쉬운( 물론 쉽진 않지만 없으면 더 어려움...흐흐) 알고리즘이 만들어지며, 언어의 원초적(?)인 기법(구현법,사용법)인 구조적(structured)인 사용이 가능해집니다. 그런 예로써 나중에 배우겠지만 프로시져(부프로그램)라는 것이 이 스택이라는 구조가 없으면 말짱 꽝입니다... 자아...이제부터 아주아주 쉽게 설명을 합니다.... ==================== 오늘의 주제 : 스택 ==================== 자아 우선 스택이란 단어를 머리에서 싸악 지우세요. 그리고는 접시가 한 스무개 정도 놓여있는 선반을 떠올려 봅시다. 자아... 떠올려 지십니까? 거기서 접시 한개를 꺼내 봅시다.... 여러분은 어디에 있는 접시를 꺼냈습니까? 백이면 구십구(?) 전부 맨 위에 얹혀있는 접시를 꺼냈죠? 만약에 중간에 끼어 있는 접시를 뽑아 낼려면 위에 있는 접시를 들어내는 불필요한 작업을 감수해야 합니다. 자아 그럼 접시를 하나 올려봅시다. 여러분은 어디에 올리셨읍니까? 맨위에 올리셨습니까? 그렇습니다.. 만약에 중간에 끼워넣는 작업은 불필요한 에너지(?) 소비를 가져옵니다.... 영영사전을 뒤적여볼깝쇼? stack : orderly pile or heap of things one above another 순서대로 차곡차곡 쌓여있는 어떤 무엇이라고 합시다. pile은 뭐구 heap이 뭐지?..음...역시 영영사전은 보기 힘들구먼. 우리가 어셈 프로그램을 짤때.... 명령어들의 집합(코드)들을 우리가 원하는 데로 나열합니다. 또한 명령을 수행하기위하여 정보를 저장할 곳이 필요할때 데이타 저장소 등을 초기화(정보넣기 혹은 메모리만 확보하기)를 합니다... 그런데 스택은 그냥 메모리를 확보하는게 아니고 얼마만큼의 메모리를 쓰겠다 하는 몇바이트의 정보만 씁니다. 또한 스택에다가 처음에는 아무것도 할 수가 없습니다.. 코드나 데이타는 자기 나름대로의 정보가 저장돼야지만 수행을 하지만 이놈의 스택은 처음엔 정보가 아무것도 없습니다. 단지 스택의 크기만 알고 있습니다... 프로그램이 수행되는 과정에서 스택이 커졌다 작아졌다 하거든요. 엄밀히 말하면 그렇진 않지만 우선 그렇게 알아둡시다. 이따가 또 나오거든요...흐흐...... 방금 내가 위에서 한 말은 이해가 안가는 분들이 태반일껄요? 성급해 하시지 마시고 천천히 배워 가봅시다... 우린 저번 강좌에서 레지스터란걸 배웠습니다... 기억이 나실런지 모르지만 레지스터의 갯수는 몇개 안됐죠? 그런데 이 컴퓨터란 놈은 레지스터에서 계산이나 어떤 작업을 한다고 했지 않습니까?....한번 해봅시다... 우리가 AX 라는 레지스터에 8이라는 값을 넣었고 무슨 일을 했습니다. 그런데 다음 명령에서 덧셈이나 곱셈을 할려고 AX 에다가 덧셈을 하기위한 정보(2라고 합시다)를 저장합니다....AX에 값이 바뀌었겠죠? 자아..그런다음 AX엔 두번째 작업을 한 데이타가 들어가버렸어요. 아니 근데 이게 웬일이랍니까? 두번째 작업 하기전에 저장한 값이, 즉 덧셈하기 전에 쩌어기 있는 데이타(8)가 다시 필요하드라 이 말입니다... 그렇다면 또 AX에다가 그 데이타를 넣기위하여 메모리를 또 뒤?㈍하는군요...아아...이게 무슨 짓이래요..완전한 노가다 입니다.. 스택이 해결해줍니다... 첫번째 작업 후에 스택에 저장한다음 두번째 작업한 후, 스택에 있는걸 부릅니다...간단합니까? 아주아주 간단하죠? 스택에 레지스터의 값을 집어넣는 명령이 푸쉬(PUSH)고요. 빼내는 명령이 팝(POP) 이에요.... 결국 이렇게 ┛눼求.. MOV AX,8 <----- AX 에 8을 넣으라는 명령 ...... <----- 어떤 작업들 (AX의 값이 변치 않는다 가정) PUSH AX <----- 요게 포인트(중요!!) MOV AX,2 <----- 2를 넣어라... (AX의 값이 변치 않는다 가정) ...... <----- 어떤 계산 명령들 POP AX <----- 두번째 중요포인트 이때 AX에 8이라는 값이.. 자아 이제 뭔가가 떠오르나요? 위의 과정중에 아주 중요한 놈들이 참여합니다.... SS 와 SP 가 부부사이라서 돼도록이면 건드리지 않습니다... 바로 위의 과정에 이놈들이 참여를 하기때문에 섣불리 건드려서는 안되는 것이죠... SS 에는 무엇이 저장되어 있을까요? 네에...그렇습니다... 바로 스택구조가 사용할 메모리의 세그먼트를 가리키고 있습니다.. 그리고 SP 는? 아주 중요합니다.. 프로그램 시작 제일 처음엔 바로 이 스택의 크기가 저장되어 있습니다... 자아 봅시다... SS:6D14 --> ? SP:0000 처음에 SP에는 0100이 ? 0002 들어가게 됩니다... (스택크기) .... ... 그런데 PUSH 라는 명령을 ? 00FE 만나게 되면 SP가 감소하게 ? 0100 되는군요... 00FE로 말이죠.. 이해가 오십니까? 자아.. 이제 다시 아까의 명령들과 스택의 변화를 살펴봅시다. 우리가 명령을 실행하기 전의 스택의 상태가 이렇다고 봅시다.. 편의상 SS 는 생략합니다... ? SP:0000 지금 SP에는 0014라는 값이 .. ... 들어있습니다... 물론 그보다 ? 0010 더 큰 주소에는 우리가 하려는 ? 0012 명령들 전에 PUSH 되었던 값들이 ? 0014 <-SP 들어있을 것이다... 자아 인제 MOV AX,8 이 되었고 여러명령이 실행된다음 PUSH AX 라는 명령이 실행되었을 때의 스택을 살펴보자 ? SP:0000 자아... 여러분의 예상과 맞습니까? .. ... SP 의 값이 바로 0012 로 변하면서 ? 0010 0014라는 주소에는 8 이라는 값이 ? 0012 <-SP 들어가 버리는 거에요... 8 0014 자아 또 우린 무엇인가를 또 실행했고, 다시 POP AX 라는 명령을 만났다고 봅시다... 스택을 또한 살펴봐야죠? ? SP:0000 8 이라는 값을 AX 에 보내주고 .. ... SP 는 값이 증가하네요 ? 0010 0012 에서 0014 로...그쵸? ? 0012 8 0014 <-SP 스택의 중요성은 여기에 그치지 않습니다... 여기까지 우린 스택이 어떻게 작동하는지를 알게 되었죠? 스택내부의 작동을 아는것은 프로그래밍 하는데 그리 중요한 일은 아닙니다.. 하지만 모르게 되면 프로그램의 이해가 좀 어렵죠.. 우린 PUSH 와 POP 이라는 명령이 스택작동과 밀접하다는걸 알게 되었습니다... 스택과 관계있는 명령이 또 하나 있습니다... 그러나 나중에 알게됩니다... 프로시져(부프로그램)라는 것에 관계가 있는데요... 여길 하려면 좀더 복잡한 얘기가 나오게 되므로 다음강좌로 미뤄야겠네요... 또한 스택 SS 의 첩인 BP 의 작동도 프로시져와 연계되어야 겠네요.... 여러분은 어셈으로만 큰 프로그램을 짜기는 어렵습니다.. 작은 프로그램이라면 문제가 별루 없지만서두 어셈으로만 한다면... 그 중대한 노동의 댓가가 그리 크지 않을경우 매우 상심하게 됩니다... 그래서 대부분의 경우 C 와 어셈을 병합해서 큰 프로그램을 짜는 경우가 많습니다.. 하지만 그게 그리 쉬운게 아닙니다.. 알아야 할 것이 조금 많습니다.. 이때 또 스택이라는 것이 아주 중요합니다... 이 스택이란 놈은 아주 능력이 많은 놈입니다.. 하지만 잘못 사용할경우 심각한 문제를 발생합니다. 이 심각한 문제점만을 논하고 나서 강좌를 마칠까 합니다. 우리가 PUSH 와 POP 이라는 과정에서 중요한 것을 잊지 말아야 합니다. 그 중요한 것이 바로 이겁니다.. 제일 나중에 PUSH 한 값이 처음에 POP 이 된다는 겁니다.. 4라는 값을 푸쉬하고 8이라는 값을 또 푸쉬했다고 봅시다. 이때 4라는 값을 POP 할수는 없다는 겁니다... 그 4라는 값을 읽고 쓰기 위해선 절대 SP 의 조작으로서 하지 맙시다. 제발 그런 불상사가 생겨선 안됩니다.. 그래서 BP가 존재를 합니다.. 하지만 BP가 있다손 쳐도 아직도 프로그래머가 고심해야 할 점이 있습니다.. 우리가 언제 어느 시점에서 PUSH 를 하고 POP 을 해야 하는지를 꼭 직시해야 합니다. 이건 정말 어려운 문제입니다.. 몇번전에 푸쉬한 값을 해야하는지를 알아야하는 것입니다 이것은 직접 프로그램을 짜면서 스스로가 느껴야 합니다. 자아..그리고 꼭 예제를 봐야하는군요... 그럼 다음에 봅시다... 별로 쉽게 설명 못한것이 조금 아쉽지만... 언제나 질문을 받습니다... 그럼... 여수 똘마니 송균상 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 428번 제 목:[강좌] 어셈초보 -스택 Q&A- 올린이:nowngm (게임제작) 97/11/27 15:05 읽음:598 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 47번 제 목 : [강좌] 어셈초보 -스택 Q&A- 올린이 : timebomb(이시원 ) 95/12/15 12:40 읽음 : 646 관련자료 없음 ----------------------------------------------------------------------------- 반갑습니다 게제포 여러분들 !! 인터럽트에 대해서 강좌를 쓰는 중인데 해야 할 말이 너무도 많아서 편집에 고심하는중 스택에 대한 질문이 메일을 통해 들어온즉, 이렇게 Q&A로 명명하여 스택에 대해 더 자세히 논해볼까 합니다. 우선 스택을 보기쉽도록 한번 그려봅시다. 8바이트의 스택 영역이 할당되었다고 보자구요. SS:생략 SP = 0006 0004 0002 0000 값 = ? ? ? ? ^ 요렇게 되어 있다고 머리속에 그리고서는 명령을 해봅시다. 그리고 레지스터 AX에는 45, BX에는 23, CX에는 12, DX에는 5 라는 값이 들어있다고 치고요. 일련의 명령들을 만났다고 봅시다. PUSH AX PUSH BX PUSH CX POP BX PUSH DX 자아...인제 요런 명령들을 차례대로 그림(?)을 통해 이해를 도모합시다. PUSH AX 라는 명령 후 스택의 상태 SP = 0006 0004 0002 0000 값 = 45 ? ? ? ^ PUSH BX 라는 명령 후 스택의 상태 SP = 0006 0004 0002 0000 값 = 45 23 ? ? ^ PUSH CX 라는 명령 후 스택의 상태 SP = 0006 0004 0002 0000 값 = 45 23 12 ? ^ POP BX 라는 명령 후 스택의 상태 SP = 0006 0004 0002 0000 값 = 45 23 12 ? ^ PUSH DX 라는 명령 후 스택의 상태 SP = 0006 0004 0002 0000 값 = 45 23 5 ? ^ " ^ " 표시가 있는 부분이 바로 현재 SP 입니다.. 명령 실행 전에는 SP에 0006 이 있게 되고.... 실행되면서 결국 SP 의 변화는 차례대로 0006,0004,0002, 0000,0002,0000 이 되는거에요... 저기서 4번째 명령 POP BX 라는 명령후의 스택의 상태에 주목할 필요가 있습니다.. 이 명령의 진정한 의미는 바로 0002에 있는 12라는 값을 BX 에다가 넣는 것이지요? 이때 0002의 12라는 값에는 전혀 지장이 없습니다. 다시 말해서 지금 SS 에 0100 이 들어 있다고 치고 만든주소 0100:0002에 있는 값은 12가 됩니다... 이해가 오시나요? 다시 PUSH DX 라는 명령을 만나게 되죠? DX의 값 5 가 SP=0002에 들어가고 SP는 2 감소, 즉 0000이 됩니다... 그다음 우리가 또 PUSH 명령을 내린다고 봅시다.. 이때 스택은 8바이트 밖에 되질 않는데 더 집어넣을려고 했습니다... 이게 바로 STACK OVERFLOW 라는 에러가 나옵니다. 스택이 꽈악 차버렸단 말이지요..... 이런 에러는 가끔 볼수가 있습니다.... 질문에 대한 해명이 ┳렘윱歐 그럼 다음 강좌에 또 봅시다. 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 429번 제 목:[강좌] 어셈초보 -인터럽트- 올린이:nowngm (게임제작) 97/11/27 15:07 읽음:663 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 48번 제 목 : [강좌] 어셈초보 -인터럽트- 올린이 : timebomb(이시원 ) 95/12/18 12:23 읽음 : 688 관련자료 없음 ----------------------------------------------------------------------------- 안녕들 하셨습니까.. 여수 똘마니 송균상 인사 올립니다.. 내가 아주 쉽게 어셈 강좌를 쓸려고 하는데 얼마나 쉽게 썼는지는 무척 의심스럽습니다.. 제발 여러분들의 조언이나 질책 혹은 질문메일등을 주십시오. 요 강좌의 취지는 이해에 중점을 둔 만큼 너무나 어려운 부분은 잘 쓰질 않습니다.. 제가 일부러 책을 전혀 안보고 이 강좌를 쓰는 이유도 여기에 있습니다.. 모쪼록 많은 성원 부탁드립니다.. 자아 그럼 오늘의 주제는 무엇일깝쇼? ================================ 오늘의 주제 : 인터럽트 ================================ 자아..또 인터럽트란 단어를 해석해볼깝쇼? interrupt : 끼어들다. 방해하다. ...뭐 대충 이런 뜻인가 봅니다. 내가 항상 해오는 방법 --> 인터럽트란 단어를 우선 싸악 잊어버립시다. 1.하드웨어 인터럽트 컴퓨터의 역사를 아주 멀리 거슬러 올라가 보면 폰노이만이란 사람이 나옵니다.. 이름을 보니 독일사람일까요?...아니면 말구... 어째튼 이사람의 가장 중요한 업적은 이거라고 하데요... 컴퓨터에 명령을 사람이 직접 주지 않고 이미 명령을 써논것을 그대로 컴퓨터에 입력하는 거래요... 요사람이 나오기 전엔 아마도 스위치를 올리고 내리고 함으로써 명령을 내렸나 봅니다.. 근데 이사람이 바꿔놨다고 하더군요.. 폰노이만이란 사람의 이런 방법을 폰노이만머신 혹은 방식이라고 하는데요. 이건 오늘날까지도 쓰이는 방법입니다. 바로 우린 코드(명령의 나열)를 메모리에 넣고 그걸 차례대로 혹은 원하는대로 수행하게 해서 컴퓨터가 작동하게 하는거죠... 설마 이걸 눈치 못채신 분들은 이 강좌를 보지도 않겠죠?....흐으. 그런데 이 방식의 문제점이 있습니다. 무슨 문제점이냐고요? 명령들을 수행해가는데..만약에 명령의 순서에 상관없이 무엇인가가 어떤 시점에서 꼭 실행되어야 한다고 봅시다... 잘 이해가 안오나요? 그럼 다르게 말해볼까요? 자기 자신이 컴퓨터 입니다. 그런데 코드를 어디서부터 실행하고 있는디. 원래는 자기가 하던 일을 멈추지는 않습니다..그런데 그 명령을 멈추고 다른 일을 해야하는 경우가 생깁니다.. 이런 예는 조금 이따가 나옵니다.. 자아...이제 감이 좀 오십니까? 이때 우리는 코드의 진행을 끊어버려야합니다.. 그리곤 우리가 하고싶은 일을 해야합니다. 또한 방해한다고도 말할수 있죠? 또 그 하고 싶은 일이 끼어든다고도 말할 수 있을까요? 인터럽트란 놈의 역할이 바로 이겁니다... 좀더 정확한 이해를 위해 예를 두가지만 들겠습니다... 두가지 밖에 지금은 생각이 나질 않네요....흐으..... 자아... 오락 프로그램을 짭니다.. 아니면 오락을 합니다... 우린 프로그램 내에서 비행기가 움직이고 총알이 나가고 하는것을 보게 됩니다.. 그쵸?..안해본사람 있습니까? 그런데 여기서 뭔가를 궁금해 해보신적이 있으실까요? 우린 키보드의 어떤 키만 누르면 총알이 나가지 않습니까? 당연히 나가드라구요... 그런데 비행기는 계속 움직이네... 어어..이상하네.. 만약에 내가 키보드를 눌렀을 때에 비행기가 움직이는 것이 실행되고 있다면? 네에...인제 짐작이 오십니까? 그렇습니다.. 키보드가 눌려지면(정확하게 말하면 눌려지고 떼어질때) 무조건 어떤 루틴(코드)을 실행하도록 해야합니다... 코드가 내리는 명령이 아닙니다...그 프로그램 내에서 순서적으로 실행되는 명령이 전혀 아닙니다.. 단지 키보드가 눌려지면 알아서 어떤 루틴을 실행하게 됩니다.. 이 루틴을 키보드 인터럽트 루틴이라고 합니다... 또 하나 예를 들어볼까요? 혹시 여러분은 통신을 하면서 컴퓨터 음악을 들어보셨습니까? 그리고, 오락을 할때도 음악은 거의 항상 빼놓질 않죠? 그리고 또한 윈도우즈에서 그림을 그리면서 프린팅을 해보신적은 있습니까? 이걸 뭐라고 하나요? 멀티테스킹?.... 네에..맞습니다... 솔직히 말하면 명령어 두개이상이 한꺼번에 동시에 실행되지는 않습니다.. 아니 그럼 대체 어떤 방법으로? 바로 컴의 내부 시계(?)를 이용합니다... 우린 이걸 시계(클럭 또는 타이머)라고 표현 합니다만... 우리가 보통 말하는 시계는 아닙니다... 단지 1초에 자기가 지정한만큼의 인터럽트가 걸리게 만들수 있습니다.. 초당 18.2번 만큼이 아마 제일 느릴껄? 머리 똑똑하신 분들은 느끼셨을런지도 모르지만... 컴퓨터 내부에 시계가 있어야만 우린 어떤 두가지 작업을 일정시간씩 나누어서 일을 할수가 있습니다...이 작업이 빠르게 왔다갔다리 반복되므로 우린 별로 못느끼고 동시에 실행되는것 처럼 보이는거죠..... 이제 뭔가가 오십니까? 이런 종류의 꼭 끼어들기나 방해를 해야지만 뭔가를 할수가 있습니다. 우리가 이런 인터럽트라는게 없었다면 컴의 사용은 아마 불가능(?) 했었을런지도 모릅니다... 우리가 여태 얘기한 것들은 하드웨어 인터럽트 입니다... 하드웨어 인터럽트?....아니그럼 인터럽트가 종류가 또 있단 말인가? 네에....있습니다... 우린 알아야 할 사실이 있습니다.. 우리가 진정 인터럽트라고 불러야 하는것은 하드웨어 인터럽트입니다. 나중에 배울 소프트웨어 인터럽트는 진정한 의미의 인터럽트가 아닙니다. 인터럽트가 아니라는 소리가 아니고 진정한 의미의 인터럽트가 아니라는 겁니다.. 흐흐흐. 이유는 다음에 나올껍니다... 2.소프트웨어 인터럽트 소프트웨어 인터럽트는 대강 이렇게 설명할 수가 있겠네요. 여러분들이 아주 흔하게 자주 너무나도 필요한 어떤 명령들의 집합들이 있다고 봅시다. 이런 것들은 주로 도스나 바이오스(컴내부루틴)등에서 많이 볼수가 있는데요... 정확한 표현은 아니지만 이렇게 생각하시면 편합니다.. 우리가 도스를 OS 라고 부르죠?..이게 있어야만 프로그램 실행이 가능하죠? OS 는 Operating System 의 약자인디... 이게 뭔뜻일까요... 말 그대로 작동기계(구조)라고 할수 있네요... 깊이 표현하면 우리가 어떤 명령을 컴에게 내릴때 아주아주 자주자주 쓰이는 것들은 바로 이 OS 안에 루틴(명령의 집합)이 있어요... 이걸 바로 소프트웨어 인터럽트라고 부릅니다... 단지 우리가 불러서 써야하는거에요... 하드웨어 인터럽트와는 달리 우리가 꼬옥 불러야지만 실행이 됩니다. 일례로 디스크의 파일들 제어, 화면 제어(글씨나 그림 쓰기 읽기) 등등은 우리가 꼭 명령을 내려줘야지만 실행이 되는거에요.. 성격이 전혀 틀리죠? 여기까지 우리는 하드웨어 인터럽트와 소프트웨어 인터럽트의 차이점을 명백히 해야 합니다.... 지금 저의 인터럽트 강좌는 단지 소개에 불과합니다.. 알아야 할건 아직도 수없이 많으니까요.. 다음 강좌는 프로씨져 입니다... 그런데 이 프로씨져라는걸 배우고 난 후...우린 스택,인터럽트,프로씨져를 한꺼번에 다시 보게 됩니다... 이 세가지가 밀접하게 관련되어 있습니다... 우선 여러분의 상상에 맡깁니다... 12월도 점차 우리곁에서 멀어져 갈려는 찰나이네요... 이 해가 가기전에 우리가 한해동안 무엇을 얻었는지 생각해 보심이.... 여수 똘마니 송균상 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 430번 제 목:[강좌] 어셈초보 -프로시져- 올린이:nowngm (게임제작) 97/11/27 15:09 읽음:601 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 49번 제 목 : [강좌] 어셈초보 -프로시져- 올린이 : timebomb(이시원 ) 95/12/19 14:05 읽음 : 642 관련자료 없음 ----------------------------------------------------------------------------- 후후... 오랜만이네요... 게제포 여러분들... 그래도 꾸준히 읽어주시는 분들이 계셔서 눈물을 머금고 계속 할랍니다... 흑흑흑... 전번 강좌가 인터럽트 였는데 솔직히 너무 부족한 점이 없지 않습니다. 하지만 너무 깊게 들어가다 보면 아직 배우지도 않는게 속출하기에 어쩔수 없는 처사 이므로 용서를......헤헤...... 오늘의 주제는?... 프로시져 입니다.... ======================= 오늘의 주제 : 프로시져 ======================= procedure : an action or set of action nacessary for doing someting. 무언가를 하기위해 필요한 일련의 행동들 ?? 라고 해석해도 돼남? 여러분이 프로그램을 길게 짜다보면 어떤 똑같은 명령, 또는 비슷한 명령들의 나열이 생기는 수가 있습니다... 예를 들어 봅시다. 숫자를 4개를 입력하면 두수씩 더해서 출력하는 프로그램을 짰다고 생각합시다... 자아 상상이 돼시나요? 그런데 여기서 덧셈이라는 과정이 두번이나 나옴을 볼수가 있습니다... 이때 이 덧셈하는 과정만 따로 떼어서 하나의 명령코드상태로 놔두고, 두수를 입력받아서 쩌어기 덧셈과정을 부릅니다... 니 일루와... 덧셈과정이 끝나면 바로 불렀던 곳의 다음으로 가지요... 그림으로 알아봅시다... 본프로그램(메인) 부프로그램(프로시져) MOV AX, VAL1 -- ADDING -- MOV BX, VAL2 CALL ADDING ADD AX,BX MOV AX, VAL3 MOV CX,AX MOV BX, VAL4 RET CALL ADDING 위에서 ADDING 이라는 이름의 프로시져를 볼수가 있죠? 메인에서 CALL ADDING 이라는 명령어가 보입니까? 여러분은 프로시져가 왜 있어야 하는지는 대강 짐작이 오실줄로 믿고 넘어가게싸와요..... 힌트: 위의 프로그램에서 프로시져라는 것이 없다면 어떠케 짜야하는가? 이거 숙제입니다.. 내 강좌 꾸준히 읽으시는 분들은 레포트 재출하쇼!! .프로시져의 잇점 위의 보기와 같이 ADD AX,BX MOV CX,AX 라는 두 명령이 원래는 메인에서의 CALL ADDING 라는 명령과 대치돼야합니다. 그렇다면? 똑같은 명령의 나열이 감히 두번씩이나 나온단 말이자나요? 자원 낭비죠?... 프로시져의 잇점 원 !! 자원낭비를 막아준다 ~~~~~ 프로시져 ADDING(이게 더한다는 말이쥬?) 이란 이름을 가지것이 실제로 BX에 있는걸 AX에 더해서 CX 로 옮겨주걸랑요? 물론 이름은 자기가 만들어주는 거지만 필히 의미있는 이름을 사용합시다.. 프로그램을 아주 보기쉽게 만듭니다.. 프로그램을 보기 쉽게 만든다는것은 너무 중요합니다.. 자기가 자신의 프로그램을 고치기가 쉬워지걸랑요... 프로시져의 잇점 투 !! 프로그램을 보기쉽게 해준다.~~~~ 보기쉽다는것은 에러를 잡기도 쉬워진다와 일맥상통 ~~~~ .프로시져의 단점 내가보기엔 프로시져의 단점은 그리 치명적이진 않다.. 하지만 때에 따라서 조금 치명적이기도 하다...흐흐.. 프로시져의 단점은 바로 RET 이라는 명령을 만나면 불려진곳이 어디였나 하는 것을 저장하고 있고 그 저장된곳으로 가야한다는 메카니즘(내부동작구조)에 의거한다... 그래서 우린 그 메카니즘을 알아야 한다.... .프로시져와 스택이 관련한 엄청난 메커니즘... 필수!! 중요!! 외워!! 우린 이미 지금 수행되고 있는 시점이 CS:IP 에 저장되고 있다는 것을 안다.. 그리고 스택은 SS:SP , 그리고 데이타는 DS:? 에 저장되어있다는 것도 안단 말이다... 그쵸.....? (이건 우리가 하는 일이 절대 아니다) 프로그램이 마악 실행되다가 CALL (주소) 이라는 명령을 보게 되면 지금 CS:IP 의 다음단계를 스택에 저장하고요,,,,, 지금 CS:IP 에다가 바로 (주소) 를 넣게 됩니다.... 그래서 프로시져로 제어가 넘어갔죠? 프로시져를 마악 실행하다가 프로시져 끝에는 거의 항상 RET 이라는 명령을 붙이는디... 이유는 바로 이 RET 이라는 명령을 만나게 되면 CPU 가... 스택에 저장했던 것을 CS:IP 에 넣게 됩니다.... 그럼 이 프로시져를 부른곳으로 제어가 넘어 가나요...? 결국 컴 내부적으로 (우리가 하는게 절대 아닙니다) 스택이라는 구조를 프로시져와 관련해서 사용을 하는군요... 그래서 스택을 잘못 건드렸다가는 본전도 못 찼습니다.. 프로시져와 관련해서 스택을 조작할때 조심해야 할 점이 많습니다. 그러나 우린 나중에 C나 PASCAL등과 어셈을 병합하여 프로그램을 짤적에 이 메카니즘은 아주 중요하다는 것을 미리 점 쳐볼수 있다... 그리고 또한 SS 의 첩인 BP 의 사용도 점칠수가 있다... 부인 건들믄 큰일 낭께 첩이라도 건드러서 스택을 조작해야 할꺼 아녀유.... 안그류.....? 다음 강좌가 뭔줄 알어유? 바로 우린 방금 프로시져의 작동 메커니즘을 알았자너유... 인터럽트의 작동 메카니즘에 대해서 알아볼꺼여유...으흐흐 이것두 아주 중요하니끼니 기대해보세요.... 기럼. 여수 똘마니 송균상 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 431번 제 목:[강좌] 어셈초보 -인터럽트메카니즘- 올린이:nowngm (게임제작) 97/11/27 15:15 읽음:617 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 51번 제 목 : [강좌] 어셈초보 -인터럽트메카니즘- 올린이 : timebomb(이시원 ) 95/12/23 03:40 읽음 : 669 관련자료 없음 ----------------------------------------------------------------------------- 헤헤... 반가워유... 요즘 갑자기 공부할게 생겨서는 바쁘네요.... 그 공부라는거좀 알리고 넘어갈께요... 제가 어제 즉, 19일날 프램동(prog)에서 forth 라는 언어 어쩌구 하길래, 하이텔 두루물 동호회에 갔더니 forth란이 있더라고요... 그래서 공개용인 그 언어를 다운받고 강좌란을 싸그리 갈무리해서는 어제,오늘 한우물을 팠더랍니다... 전 경악에 경악을 금치 못했답니다...관심 있으시면 연락주세요. 좀더 연구한 후에 이 언어를 소개할 참입니다... 자아.. 오늘의 주제는 아주아주 중요하면서도 너무너무 할게 많네요. 저저번 주제였던 인터럽트 아시죠? 바로 그것의 두번째 얘기가 될껍니다... 하지만 어제꺼와 연결되니 조심...~~~~~ =============================== 오늘의 주제 : 인터럽트 메커니즘 =============================== 대부분의 여러분들은 BIOS 라는 말을 들어보셨나요? 그럼 설마 DOS 는 들어보셨겠지? BIOS ( Basic Input/Output System ) 기초적인 입력/출력 시스탬? ROM 은 아시죠? Read Only Memory.... 컴퓨터에서는 시스템(기종)이 다르더라도 기본적으로 문자출력이나 화면제어, 키보드 제어 등등을 같은 인터럽트로 통일합니다.. 인터럽트 몇번이 화면제어를 하는거라고 합시다... 그 인터럽트 내부에 명령의 나열들은 기종마다 다를지언정 하는 일은 똑같이 만들어 논거죠.... 그래야지만 호환성에 별반 문제가 생기지 않겠자나요..? 요 BIOS 는 보드제작사에서 만듭니다... AMI, Pheonix, 에 또 뭐가 있드라. 우린 DOS 없으면 프로그램 실행을 할수가 없죠? 요 DOS 는 저기 BIOS 를 이용하거나 직접제어를 하거나 어째튼지간에 주로 16진수로 21번의 인터럽트를 로딩(램에 적재) 합니다... 우리가 디스크나 비디오카드(화면) 키보드 마우스 등등을 직접적으로 제어를 할려고 프로그램을 짜면 다른 기종의 컴에선 안돌아갈 경우가 있습니다...즉 호환성에 문제가 있죠.. 그러나 제일 빠릅니다... 아주 빨라요... BIOS 레벨에서 프로그래밍을 하면, 즉 BIOS 인터럽트를 불러서 쓰면, 호환성은 좋지만 느리다는 단점이 있죠....흐흐. DOS 레벨은 BIOS 보다 더 쓰긴 쉽지만서두 더 느리죠...헤헤 여기서 여러분은 중요한 결정을 해야죠... 속도냐,... 호환성이냐.... 이것이 문제로다..... 어째튼 이해가 좀 힘들줄은 짐작합니다만... 이게 우리의 목적은 아닙니다... 바로 인터럽트의 메커니즘이 목적이죠.. 저번강좌 프로시져에서 스택이 관련한 중요한점 잊지 않으셨겠죠? 이게 인터럽트에도 똑같이 적용됩니다.... 즉, 프로시져가 불려질때 불러진 곳으로 나중에 되돌아 가기위해서 그 주소를 스택에 저장했자나요?... 인터럽트도 똑같아요... 인터럽트도 일련의 명령들의 나열인 만큼 그쪽으로 제어가 옮겨가서 다시 돌아와야할 주소가 저장되어야 한단 말이죠.... 인터럽트 벡터(주소?) 테이블 --------------------------- 인터럽트와 프로시져의 궁극적인 차이는 바로 이 테이블인디요... 이 테이블이 실제 메모리의 어디에 있는고 하니, 0000:0000 번지에 있어요... 제일 밑(하위)메모리에 있다고요.. 몇바이트로 돼어있냐고요?... 아마 1024바이트일꺼에요... 인터럽트가 16진수로 00 번부터 FF 번 까지고, 하나의 인터럽트가 시작될 주소를 테이블에 저장하니까 주소는 4바이트가 필요하니끼니 256(FFH) * 4 = 1024 BYTE 계산 돼남유? 자아 인제 그림으로 표현해 볼깝쇼? 프로시져는 [ CALL 프로시져이름 ] 이라는 문법을 썼자나요? 근데 원래 머신코드(진짜로 들어가는 명령)은 이름이 아니고 주소에요. 즉, CALL 3F00:0100 이런식으로 근데 인터럽트는 번호로써 해요... INT 21H 이런 식으로...자아 봅시다. 지금 메모리를 가상적으로 꾸며본겁니다...오해 없으시길... [인터럽트 벡터 테이블] 0000:0000 ? ? ? ? 0H 번 인터럽트 이런 방식은 컴의 구조에서 0000:0004 ? ? ? ? 1H 번 인터럽트 아주 여러곳에 쓰인다.. 0000:0008 ? ? ? ? 2H 번 인터럽트 테이블 방식이라고 하는데 ..... ..... ..... 이건 우리가 디스켓에 파일을 0000:0084 C7 23 19 00 21H 번 인터럽트 저장할때도 내부적으로 이와 ..... ..... ..... 비슷한 테이블 방식을 쓴다... 0000:04F8 ? ? ? ? FEH 번 인터럽트 이런 방식을 우린 이해해야한다. 0000:04FC ? ? ? ? FFH 번 인터럽트 ^ ^ | |---> 4바이트의 번지다 ,실제 그 인터럽트의 주소가 들어있다 |-----------> 실제 메모리의 번지다.. [실제 프로그램 보기] MOV AX,09H MOV DX,0234H INT 21H >----------->> 이 명령을 만나면 컴은 21H 에 4를 곱한 곳의 MOV CX,100 제일 하위주소 즉, 0000:0084 에서 4바이트를 읽게 된다.(위를보라). 거기엔 C7 23 19 00 이 있다.. 이 인터럽트의 실제 위치가 바로 여기다. 이때 INT 21H 의 다음 명령인 MOV CX,100 에 해당하는 주소가 스택에 저장된다음 CS:IP 에는 C7 23 19 00 에 해당하는 주소가 들어가서 바로 그 해당 인터럽트로의 제어가 넘어가는 것이다.... 프로시져에선 RET 명령을 만나면 다시 스택을 조작헤서 처음곳으로 되돌아가지만 인터럽트에선 IRET 이란 명령을 만나면 그런동작을 한다... 여러분은 뭔가 이상한 점을 발견하지 못했습니까? 자아, 인제 인터럽트도 하나의 루틴(명령의 나열)입니다... 이걸 여러분이 손수 만들려면 바로 자기가 짠 어떤 루틴을 메모리에 넣고, 그 루틴의 주소를 인터럽트 해당 벡터테이블에 넣어주면 돼겠죠? 바로 그겁니다... 이게 이상한 점일까요? 이건 여러분이 어느정도 눈치를 채셨습니다.. 아니그럼 대체 뭐가 이상하다는거요.... 내가 지금 설명한건 모든 인터럽트가 아닙니다... 바로 소프트웨어 인터럽트밖에 말하지 않았습니다... 저번 강좌 인터럽트를 다시 보면 아시겠지만, 하드웨어 인터럽트는 우리가 무조건 부를수가 없다고 했죠? 자아, 키보드에 해당하는 인터럽트가 아마 8번 일껍니다... 이건 INT 8H 이런 명령으로 쓰이지 않습니다.. 굳이 쓴다면 뭐 할말은 없습니다만.... 키보드가 눌려지거나 떼어지면 무조건 컴은 모든 활동을 멈추고 8번 인터럽트 루틴을 실행합니다... 머리속으로 이게 실행되는 과정이 새겨지십니까? 오락에서 콘트롤 키나 시프트가 총알이 될수 있는 원인을 제공합니다..흐으. 이 하드웨어 인터럽트에 대해선 좀더 논의를 해야하지만서두 다음으루 미룰랍니다....왜냐고요? 엿장수맴이거든요....흐흐...... 내가 할말이 쬐까 있어서요... ======================================================= 내가 하고싶은 말..... FORTH 라는 언어 ===================================================== 여러분은 C 를 배우셨는지 모르겠습니다만.... 저는 어셈과 거의 같은 동시간에 배웠습니다.... 내가 처음 베이직을 일주일만에 배웠을 당시,... 난 아아...프로그램을 이렇게 짜는구나... 했죠... C 를 배웠을때 .. 아아...그렇구나... 이렇게 돌아가는거구나.. 어셈을 접했을때... 와우...그렇군..컴이 이거군..... 그런데 전 요즘 FORTH 라는 언어를 접했습니다... 언어란 이거다... 란 생각이 파악 들었다면 여러분 믿으시겠습니까? C를 한참 하고있었던 대학1년시절 FORTRAN 을 가르치드라구요... C 보다는 막강하지는 않았지만서두 무척 쉽게 배울수 있었다는점이 매력이라면 매력이더군요... 어셈은 무척 어렵게 배웠죠... 아직도 배울게 많은걸요... 근데 컴의 구석구석을 제어하고 또 못짜는 프로그램이 없으므로(?) 이 매력두 버릴수는 없죠... C 는 고급언어이면서두 어셈과 어느정도 친하므로 제일 많이 사용되긴했죠...저두 제일 많이 사용했구요.. 근데 이 모든 장점이 한데 묶였습니다.... 베이직처럼 쉬운 인터렉티브한 방식, 포트란처럼 간단한 구조... C 처럼 강력한 언어, 어셈과 제일 친한 언어.... 맘만 먹으면 베이식이나 포트란 같은 언어는 쉽게 만들어 버릴수 있는 능력... 단점이 왜 없겠습니까만은...단점에 비해 장점이 너무너무 많은 포스!!!! 강력히 배우기를 권합니다.... 배우는 방법은 하이텔 두루물 자료실에 한글포스가 있구요. 강좌가 몇개씩 올라는 와 있지만 조금 부족하긴 하더군요. 그쪽에서 추천하는 책이 한권이 있으면 좋겠지요? 배우기가 그리 어렵진 않습니다....후후... 만약에 내 이 말을 듣고 한번 배워볼려다가 이 언어에 실망하시는 분이 혹시 있을런지는 모르지만.. 이런 사람이 생긴다면 내가 책임지고 같이 배울수있게 만들어 드립니다.. 왜 좋은지도 열변을 토합지요... 그럼 많이 많이들 접해보시길..... 정말 기원합니다... 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 432번 제 목:[강좌] 어셈초보 -포트- 올린이:nowngm (게임제작) 97/11/27 15:18 읽음:620 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 52번 제 목 : [강좌] 어셈초보 -포트- 올린이 : timebomb(이시원 ) 95/12/25 05:45 읽음 : 649 관련자료 없음 ----------------------------------------------------------------------------- 안냐세용? 아이디 기생 앤드 여수 똘마니 송균상 인사올려요. 와우..저의 강좌가 이토록이나 많은 회를 거듭하다니... 맴이 흐뭇합네다... 다음엔 뭘 할까 고민하던중, 에이 그냥 기초적인 명령어를 해볼까 했는데, 부족한점이 있어서 아직은 시기상조더라고요. 여태까지의 강좌중 너무 난해하다거나 좀더 깊게 다루었으면 하시는 부분이나 고쳤으면 하는 부분이 있으면, 가차없이 메일좀 주시와요.. 나 이거 이 말 몇번하는지 모르겠네. 꾸준히 보시는 분들이 한 열명 남짓 계시온데... 이해가 그냥 팍팍 오시남요?.. 아니면 메일을 올릴지 모르시나? 어찌됐던 오늘 강좌를 시작합니다... 오늘의 주제는 바로 포트 포트 포트 포트.... 외워!! ================== 오늘의 주제 : 포트 ================== port : harbour ... 항구?... 아니야 이거보단 이게 더.. portable : can be easily carried or moved; quite small and light.. 포터블 , 쉽게 움직이고 옮길수 있는.. 결국, 매우 작고 가벼운... 흐음.. 우선 그렇다고 치자고요... 뉘앙스가 팍팍 풍깁니까? 자기 자신의 사운드카드(사블류,에드립,옥소리등)나 모뎀이나 마우스 등등 사용시 문제를 느끼셨던 부분이 전혀 없으셨나요? 일례로, 특히 컴으로 다른건 잘 안하고 오락만 주로 하시는 분들에게 이런 현상이 쬐까 있는디요... "아니 이게 뭐야... 나 분명히 사운드카드도 있고 스피커까지 있어. 이 오락 저 친구집에선 소리 나든디 왜 내껀 안나지?.." 아무래도 불법복사 분위기가 물씬 나죠? 키야아아... 어떤 사람이 모뎀을 2400bps 쓰다가 훨씬 빠른 14400bps로 사가지고 위풍당당히 집에와선 가르쳐준데로 케이스 열고 꼽았어요.. 어어... modem port not found! ??? port ??? 위의 두분다 다시 어디선가 컴도사에게 물어봤더니... 포트를 맞춰줘야한다는 이상한 말을 하네?... 아니 그럼 나보고 어쩌란 말야. 포트가 뭐여...젠장 컴퓨터 누가 만들었어...이거 무식장이 서러워살겠나. 여러분이 프로그래밍을 어느정도 배우지 않는 이상 이 포트란 말은 저렇게 사운드카드나 마우스, 모뎀에서 들었을꺼에요?...그쵸?....네에?...한번도 안들어봤다굽쇼? 허어...그럼 어디가서 우선 듣고 오슈...쌩판 안들어본거 이해할려면. 쬐까 힘든디....흐음.... 여러분은 여태까지 저의 강좌에서 메모리가 어떻구 인터럽트가 어떻구 레지스터가 어떻구 그런류의 말을 들었어요... 아니 근디 대체 디스크에서 파일을 읽어드리구 소리는 어떠케내구.. 모뎀은 어떠케 제어하구 프린터, 마우스, 모니터 등등은 대체 워떠케 혀야지 명령을 내릴수 있는거지? 아니그럼 이런 모든 명령이 존재한단 말인가? 모르시는 말씀,.. 이런 모든 명령을 CPU 혼자 다 한다면 아마 CPU 머리가 터져버릴꺼요.. 너무 많은 명령이 존재하면 컴이 느려진다는건 아실랑가 몰라.... CPU 와 주변기기(위에서말한 모니터,마우스등등)가 의사소통,즉 주변기기에게 이렇게 해라 저렇게 해라란 명령과 관계된 명령은 아쉽게도(?) 따악 두개에요...뭐냐고요? IN 하고 OUT 이요... 예전에 레지스터 강좌에서 AX 와 DX 가 주변기기 제어할때 큰 역할을 한다고 하지 않았습니까? 바로 여깁니다... 만약에 어떤 주변기기에게 어떠케 해라란 명령을 내리구 싶으믄 DX 에다가는 그 주변기기의 번호(이름이나 마찬가지지뭐)를 넣고 AX (또는 AL) 에다가는 그에따른 정보를 넣고, IN 이나 OUT 명령을 내립니다... 이때 컴은 어떤 작업을 할까요? DX 에 해당하는 번호(값,숫자)를 우린 포트번호라고 불러요.. 그 해당 포트에 AX나 AL에 들어있는 값을 넘겨주거나... <== OUT AX나 AL에다가 해당 포트에서 값을 집어넣어 줍니다... <== IN 자아 여기서 우린 한가지 집고 넘어가죠.... 주변기기와 CPU(중앙처리장치,명령들을 분석,처리하는곳)는 따로따로 자기 맡은바 일을 합니다... 결국 멀티테스킹을 해요.. 주변기기에 명령을 내리는 방법은 단지 IN,OUT 뿐이에요.. 아니그럼 주변기기는 자기 맘데로 일을 하는겁니까? 정답은 네에...그렇습니다 입니다... 증명해줘요?.....내가 힘이 있나...하라면 해야지.. 여러분 !! IN,OUT 명령으로 모니터에게 계속 저긴 흰색점찍고 요긴 빨간색 점찍고 란 명령을 쉬지않고 계속 내리란 겁니까? 한번만 내려야죠.. 계속 찍는건 모니터가 알아서 해야죠.. 왠지 다른방법이 있을것 같다고요?...좋아요...그렇다고 칩시다. 여러분은 오락을 하다가 ALT+CTRL+DEL 눌르면 컴을 끄거나 소리나는 오락을 다시 하지 않는 이상 그 삐하는 소리 계속 들리시던 경험 없나요? 사운드카드는 "얌마 멈춰" 하지 않는 이상 계속 소릴 내거든요... 이런 경우 없다고요?... 나참...좋아요..또 하나... 여러분은 컴에다가 날짜하고 시간등을 입력하셨죠? 그거 컴을 완전히 껐다가 나중에 다시 틀으면 어어..시계가 정확하네?...컴 껐는데...컴의 내부시계두 주변기기에요.. 컴 내부시계는 자체에 충전지를 내장한다고 하드라고요.. CPU 가 명령을 내리지 않아도 그놈은 계속 돌아가요... 이제 주변기기는 자기 혼자서도 돌아간다는거 이해했나요? 이 컴퓨러라는거 누가 만들었는지 몰라도 오묘하지 않습니까? 내가 왜 삼천포로 빠졌지? 결국 포트라는건 주변기기와의 통신하는 주소(?)라고 표현해도 무리가 없을꺼 같습니다... 근디 이놈의 포트라는거 거의 대부분 컴에서 꼬옥 있어야 될 주변기기는 포트번호가 거의 지정이 돼어있어요.. 즉 시계나 내장스피커 그외의 아주 여러가지는 거의 포트번호가 일정합니다... 근데 다른 주변기기 모뎀,사운드카드 등은 그렇지 않아요.. 자기가 사다가 꽂는 카드같은거 말이죠..... 왜 그렇게 했냐고요?...이렇게 하지 않으면 새로운 주변기기의 발전은 제로에 가깝지 아마? 어째튼 우리는 자기 자신의 모뎀이나 마우스 사운드카드등의 포트번호를 알아야지만 어떤 프로그램에서 그걸 요구할때 적을수가 있지 않습니까.... 초보들은 이걸 꼭 모르더라.. 또 하나 잊지 말아야할 사실이 있는데... 모니터(정확히 하자면 비디오카드)를 제어하기위한 포트번호가 한개가 아니라는 겁니다... 약 10개가 넘을껄요... 다른것들도 마찬가지에요... 사운드카드도 포트번호가 10개는 아마 안돼나...어째튼지간에 많다 이겁니다... 그래야 이것저것 시키죠... 요런 장점이자 단점 때문에 포트가 충돌해서 요건 요 포트로 바꿔야한다 이래야한다 라는 말이 나옵니다.. 아니그럼 우리가 화면에 글씨하나 찍기위해서 IN,OUT 그 복잡한 일련의 명령들을 팔아프게 때려야합니까? 이히히...요게 바로 인터럽트가 있는 요인 아닐깝쇼? 인터럽트안에는 아주 유용한 주변기기와의 의사소통에서 잘 쓰이는 것들만 차곡차곡 모아놨어요.. 그 인터럽트의 명령들을 우린 볼수도 있어요... (인터럽트 루틴안에 IN,OUT 명령이 많이 보이겠죠?) 또한 바꿀수도 있고요... 우리가 직접적으로 IN,OUT 명령으로 주변기기에게 명령을 내린다면 인터럽트를 쓰는것보다 더 훨씬 빨르게 주변기기를 제어할수가 있답니다... 이게 바로 시스템프로그밍이라고들 하데요.... 허어.....오늘 너무 많은걸 알려줄려고 했나...쩌업.. 계속 어렵다싶은 얘기를 해야하니 이것도 곤욕이네...음.. 어셈을 너무 어렵게 보시는 이유중 하나가 이 포트와 관련된건데 솔직히 이 IN,OUT 명령은 어셈공부하고는 관계가 거의 없다고 해도 과언이 아니에요. 차라리 주변기기의 작동이나 사용법과의 관계된 겁니다.. 여러분은 여기서 많은 궁금증이 있을줄로 알아요.. IRQ 가 뭐죠?... DMA 는 뭐죠?..또 PPI 는요? 후후..너무 많은걸 알려고 하지 마세요...머리 터집니다... 기럼... 여수 똘마니 송균상 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 433번 제 목:[강좌] 어셈초보 - Q & A - 올린이:nowngm (게임제작) 97/11/27 15:20 읽음:586 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 53번 제 목 : [강좌] 어셈초보 - Q & A - 올린이 : timebomb(이시원 ) 95/12/26 12:41 읽음 : 625 관련자료 없음 ----------------------------------------------------------------------------- 안냐세요? 크리수마수날 포트에 대해서 올렸는디 다음날인 오늘 오후에 들어와보니 16명이나 읽어주시다니...와아아 감동.. 이번은 Q&A 파트입니다.... Q : 하드웨어 인터럽트에서 1초에 18.2번이 호출된다고 했는데 그럼 키보드 인터럽트도 1초에 18.2번 호출되면서 키가 눌려졌는지를 검사하나요? A : 1초에 18.2번 호출(실행)되는 인터럽트는 08H(H:HEX) 번입니다.. 이것은 항상 18.2번이 호출되는건 아닙니다.. 자기 자신이 시계를 조작하면(포트로) 더 빨리 호출되게 할 수도 있습니다... 키보드 인터럽트는 09H 번입니다.. 이것은 키보드가 눌려지거나 혹은 떼어지면 무조건 이 루틴을 실행합니다.. 1초에 18.2번 만으로 키보드가 눌려진지를 검사할수 있다고 보시나요? 키보드 인터럽트는 키보드가 눌려지거나 떼어지면 항상 에누리 없이 실행됩니다... 내부 시계 인터럽트와 키보드 인터럽트는 둘다 전혀 상관이 없는 하드웨어(!!!) 인터럽트 입니다. Q : 인터럽트 벡터 테이블 방식이 디스크에서도 쓰인다는데 디스크에선 어떤 식으로 쓰입니까? A : 정말 죄송합니다.. 제가 말을 좀 이상하게 해서 이런 오해의 소지가 발생했나 본데요.... 인터럽트 벡터 테이블에서 그 테이블에 그 번호에 해당하는 주소가 저장된다고 하지 않았습니까? 그래서 테이블에 있는 주소로써 어떤 번호에 해당하는 인터럽트의 주소를 찾아감으로써 간접적으로 호출(실행)하게 되는 방식이지요? 디스크와 인터럽트와의 근본적인 관계가 있는것이 아니고, 디스크에서 파일을 저장하는 방식(FAT) 이 이와 비슷하단 겁니다. 단지 그 방식, 간접적인 방식, 테이블에 의한 방식이 비슷하단 겁니다.. 오해가 풀리셨나요? 디스크에서 파일을 저장하거나 지우거나 하는 방식에 있어서 중요한 한가지는 FAT 입니다... File Allocation Table 의 약자입니다... 여기서도 테이블이란 말이 나오지요? 이건 자기 자신이 DOS 나 UNIX 등의 오퍼레이팅 시스템을 만들고 싶지 않는 이상 그리 중요한건 아닙니다... 왜냐하면 파일들을 쓰고 읽고 하는 과정은 DOS에 있는 소프트웨어 인터럽트 21H 에서 더 편리하게 해주니까요.. 그러니까 우리가 파일을 조작하기위해 꼬옥 FAT 를 알아야 할 필요는 없습니다.. Q : DOS에서 프로그램이 실행될때, 언제나 인터럽트 21H번이 실행되나요? ..그렇다면 왜그런지.?? 21H가 대체 어떤 일을 하길래? A : 언제나 실행되냐구요? 그건 아니고 우리가 불러서 써야지만 실행이 됩니다.. 인터럽트 21H 는 아주 유용한 루틴들이 많이 있습니다. 앗.!!! 많이 있다구요? 한 번호의 인터럽트가 많은 일을 한다구요? 하하하...그렇습니다.. 21H 를 호출하기 전에 레지스터 AH 에다가 해당 값을 넣습니다.. 이게바로 21H 에 어떤 명령을 내리는 겁니다.. 이해가 잘 오지 않는가요? 봅시다... MOV AH,02H MOV DL,'Y' INT 21H 여기서 우린 AH 에 넣은 값에 주목합시다... INT 21H 가 하는일은 저기 AH 에 들어있는 값에 따라 바뀝니다.. 02H 가 들어있으면 DL 에 들어있는 값을 ASCII 코드로 인식을 하고 그걸 화면에 출력합니다.. 즉 화면에 Y 를 출력하는겁니다... INT 21H 의 중요한 여러가지 역할을 보면요... 문자나 문자열의 입력이나 출력(물론 ASCII), 디스크나 파일조작, 사용자 인터럽트 조작, 일반적인 RAM 상태조작 등 아주 일반적이고도 자주 많이 쓰이는 것들에 대한 루틴들이 많습니다... 이것들의 정보는 시스템 프로그래밍 전문서적이나 기술사전, 어셈 전문서적등에서 찾아볼수 있습니다..... 참고로 제가 애용하는 서적을 적어봅니다... ========================================================= PC INTERN system programming : Tischer : Abacus --------------------------------------------------------- IBM PC (XT / AT / PS/2) 기술사전 : 한성국 : 집문당 --------------------------------------------------------- 마이크로소프트 매크로 어셈블러 바이블 (한국어판) 이재진 역 : 인포북 원서는 The Waite Group's 에서 Nabajyoti Barkakati and Randall Hyde 저 ========================================================= 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 434번 제 목:[강좌] 어셈초보 -포트아키텍쳐- 올린이:nowngm (게임제작) 97/11/27 15:22 읽음:611 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 54번 제 목 : [강좌] 어셈초보 -포트아키텍쳐- 올린이 : timebomb(이시원 ) 95/12/30 11:47 읽음 : 654 관련자료 없음 ----------------------------------------------------------------------------- 안냐세요...게제포 여러분들... 이번강좌는 초보에게 적당한건 아니지만, 포트에 대한 further study (깊은 공부)를 위해서 마련합니다.. AT 에서의 포트의 할당을 우선 봅니다.. XT 나 PS/2 기종에서는 다를수 있음을 알려드립니다.. 컴 내부의 시계(timer) : 40h ~ 5Fh 키보드 : 60h ~ 6Fh 인터럽트 콘트롤러 : 20h ~ 3Fh , A0h ~ BFh 하드 디스크 : 1F0h ~ 1FFh 코프로세서 : F0h ~ FFh 플로피 디스크 : 3F0h ~ 3F7h 병렬 포트 : 370h ~ 37Fh , 270h ~ 27Fh 직렬 포트 : 3F8h ~ 3FFh , 2F0h ~ 2FFh DMA 관련 : 0h ~ Fh , 80h ~ 9Fh , C0h ~ DFh 물론 이것보다 더 있습니다만 중요한것만 적어 보았습니다.. 여러분이 보통 주변기기라고 하면 컴 내부의 마더보드(가장 넓은 기판)만 빼고 다른 여러가지 등을 주변기기라고 생각했을 것입니다... 엄밀히 말하면 주변기기가 마더보드 내에도 있습니다.. 즉, 코프로세서나 내부시계 같은거죠.. (근데 이걸 주변기기라고 부르나?... 음...헷갈리네..) 해당 포트에 IN, OUT 명령을 내림으로써 주변기기를 제어할수가 있다는건 이제 이해가 오십니까? 이제 주변기기의 입장에서 서봅시다.. CPU 에서 IN이나 OUT 명령을 내리면 그 데이타가 AL(8비트) 에서 옵니다... 근데 주변기기는 이 데이타를 어디에 저장해야지만.. 그 데이타를 계속해서 쓸수가 있지 않겠습니까? 대부분의 주변기기 내에는 그들만의 레지스터가 존재합니다. 물론 우린 그 레지스터를 직접적으로 제어,엑세스 할순 없죠. 당연히 IN 이나 OUT 명령으로만 가능한 겁니다.. 여러분이 게임을 프로그래밍할때 VGA 카드를 직접적인 포트를 통해 제어해야할 때가 빈번히 생깁니다.. 이 포트를 조작한다는 말과 VGA 레지스터를 조작한다는 말이 혼용되어서 쓰이는데요.. 결국 포트와 주변기기레지스터는 밀접한 관계가 있습니다.. 보통 몇개의 포트 번호만 갖고는 그 주변기기를 제대로 명령을 내릴수가 없는 경우, 즉 더 많은 포트가 있어야지만 제대로 사용할 수가 있을경우.... 우리의 포트의 개수는 한정이 되어 있습니다.. 근데 주변기기 레지스터의 수는 할당된 포트 수보다도 많은 경우가 있습니다.. 이때 우린 인덱스 레지스터란 것을 주변기기 레지스터 내에 두어서 적은수의 포트번호를 가지고도 많은 명령을 내리게 됩니다...(강좌의 범위를 너무 벗어나므로 생략...) 위에서 생소한 인터럽트 콘트롤러란 단어가 보이십니까? 이게 바로 컴 내부의 하드웨어 인터럽트를 위한 주변기기(?)라고 볼수가 있습니다.. 이 콘트롤러가 없으면 하드웨어 인터럽트 자체는 말짱 꽝이거든요...헤헤.. 위에 적어논 포트번호는 우리가 직접적으로 제어하는 경우가 거의 없다고 해도 과언이 아닙니다... 저번에도 말했듯이 거의 소프트웨어 인터럽트(DOS,BIOS)에 더 간단하게 명령을 내릴수 있는것이 있거든요... 근데 왜 이걸 하느냐... 모뎀이라든지.. 사운드카드라든지... 비디오카드라든지.. 계속해서 발전해가는 저런 주변장치들은 DOS나 BIOS 레벨의 소프트웨어 인터럽트가 없다시피 합니다..(비디오카드는 조금 제외- 비디오카드는 그 내부에 BIOS 함수를 가진다...) 우리가 직접 해줘야되요... 이건 주변기기의 발전에선 없어서는 안될 중요한 점이죠.. 만약 포트마다 그 쓰임이 완벽히 정의 되었다고 보면... 다른 주변기기가 끼어들 자리가 있을까요? 우리가 주변기기를 달았을때 어떤 다른 주변기기와 포트가 겹칠경우 우린 충돌했다고 하죠? 이제 그 충돌이라는 의미가 가슴에 와 닿습니까? 이런 포트의 정보들은 참으로 구하기가 힘들더군요... INTEL 의 프로세서 아키텍쳐에 관한 메뉴얼이나 구해야지 정확하게 알수가 있겠네요... 하지만 다른 분들이 해놓으신 많은 라이브러리나 강좌 그리고 기술서적에서 찾으면 많이 보실수 있습니다.. 꽤나 힘든 작업입니다.. 요즘은 KNOW-HOW 가 아니고 KNOW-WHERE 라고들 하더군요.. 통신과 인터넷의 붐이 일으킨 제 4의 물결이라고 표현해도 될까요? 아아..나도 얼른 인터넷을 해봐야되는디...흑흑... 이상 포트는 여기서 마치고 다음 강좌부터는 예제를 통한 실전에 들어갈까 합니다.. 여태까지의 강좌는 실전강좌의 이해를 도모하기위한 워밍업이라고 해둘까요? 이제부턴 저도 책을 봐가면서 연구에 연구를 거듭하면서 강좌가 올라가겠네요... 전 책에 빤히 나와있는 내용에 치중하지 않을껍니다.. 그럼 책을 보지 뭐하러 강좌를 봅니까...안그래요? 통신강좌의 잇점은 바로바로 질문을 할수 있다는거 아닙니까? 저의 강좌를 보시고 음.. 이건뭘까 저건뭘까 하지만 마시고 궁금하시면 무조건 메일을 올리십시오.. 질문 메일이 없으면 전 이 강좌 때려치울지도 몰라용... 엇... 어디서 때려치우란 소리가 들리네....헤에.. 여수 똘마니 송균상 ~~~~~~~~~~~~~~ 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 435번 제 목:[강좌] 어셈초보 -주소지정방식- 올린이:nowngm (게임제작) 97/11/27 15:25 읽음:617 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 55번 제 목 : [강좌] 어셈초보 -주소지정방식- 올린이 : timebomb(이시원 ) 96/01/09 04:55 읽음 : 605 관련자료 없음 ----------------------------------------------------------------------------- 안냐세요.. 게제포 여러분들.. 나우누리 게임제작포럼 게임제작팀 프램 송균상 인사 올립니다. 준회원에서 드뎌 게임제작팀으로의 전향에 성공했습니다. 기뻐해주시와요.~~~~~ 왜이리 강좌가 늦어졌냐굽쇼 ?? 으흐흐... 제 아이디의 소유자이자 친구인 시원이란 놈이 사용료를 늦게 내는 바람에.. 크흐흐.. 솔직히 이다음 강좌의 방향을 어떠케 잡을 것인가에 대한 고민을 했습니다... 자아 오늘의 주제는 주소지정방식입니다. ========================== 오늘의 주제 : 주소지정방식 ========================== 주소지정방식에 대해서 전혀 모르는 독자(?)를 휘해 한마디로 간단히 표현하자면 이겁니다.. " 레지스터에 어떤 값을 어떠케 혹은 어디서 가져와 넣느냐 " 입니다.. 아주 간단하죠? 상수-->레지스터, 메모리-->레지스터, 레지스터-->메모리 ------------------------------------------------------- MOV AX,100 AX라는 레지스터에다가 100이라는 수를 넣는거죠? MOV AX,[100] AX 레지스터에다가 데이타세그먼트내에 옵셋 100에 있는 값을 넣는겁니다. 즉, DS:[100] 에 있는 값이돼죠... MOV AX,ES:[200] 현재의 데이타세그먼트 외의 데이타를 엑세스 하고자 할때 필수적입니다. 이것이 바로 엑스트라세그먼트(ES)의 역할이기도 합니다. 영화에서 엑스트라와 의미가 똑같죠?...헤에.... DS 의 값을 자기 맘데로 바꾸면 안된다는걸 아시길... (물론, 바꿔야할때도 있사와요.. 어떤때? 64K의 데이타 영역이 모자를때....) 결국, ES가 300 이라면 300:200 주소에 있는 값을 AX 에 넣어라란 말이겠죠? MOV [100],AX MOV ES:[200],AX 그 반대의 명령도 돼어야지 메모리에 값을 넣을 수 있겠죠? MOV 100,AX 이 명령이 가능하다고 보십니껴? 절대 결코 언제든 무조건 불가능 !!!! 왜냐굽쇼?...그걸 왜 나한테 묻나...당신 아이큐 몇자리슈? **************************************** 잡담이자 중요한 사실 : 즉, FURTHER STUDY **************************************** 컴은 값을 메모리에 저장할때 무슨 이름이 있진 않아요. 즉 주소밖에 몰라요... 너무 쉬운 사실인가? 하지만 절대 망각하진 마십시오.. 여러분이 어셈공부에 이 명확하고도 쉬운 사실을 잊어버리면 이해를 할려고 해도 되질 않기 때문이죠... 예를 듭시다. .CODE ( 코드세그먼트 영역입니다..) MOV AX,DATA .DATA (데이타세그먼트 영역이죠...) DATA DW 150 (워드,즉 두바이트의 메모리영역을 확보하고 거기에 150이란 값을 넣습니다...) 이때 MOV AX,DATA 란 명령이 실제 컴파일된 후에 명령은 디버깅을 해보시면 아시겠지만 이렇게 됩니다. 만약에 DATA란 이름의 데이타가 주소 DS:200에 있다고 하면.. MOV AX,[200] 이렇게 됩니다.. 절대 MOV AX,150이 아닙니다... 아시게쑤?? 어셈이란 일대일 언어에 컴파일러가 존재해야하는 이유지요. 왜냐구요? 기계어에서 변수란, 이름이 아니고 주소니까.. C에서의 포인터 <=====> 간접번지지정 ------------------------------------ 여러분은 이런 명령을 쓸수도 있습니다.. MOV AX,[SI] SI에 0A23 이 들어있고 DS가 1000 이라 했을때 논리주소 1000:0A23 에 있는 값을 AX 에다가 넣는 것이죠... C에서의 포인터가 어렵다 어렵다 하는데, 결코 어려울게 전혀 없습니다... 단지 주소를 간접적으로 지정하는 하나의 방식일 뿐인것이니까요... 레지스터에 주소를 저장하고 그 주소로써 값을 포인트(!!!) 하는거죠.. 이거 확실히 이해해야 합니다... 이걸 모르고서야 어셈코드의 분석은 말짱 꽝입니다.. 어셈의 배열처리 <=====> 인덱스(INDEX) 방식 --------------------------------------------- 고급언어인 C 나 PASCAL 등등 거의 모든 언어에는 배열이란 저장방식이 존재를 합니다.. 자아 여러분은 배열의 존재 이유를 아시죠? 배열이란 요소가 없다면 불편하다는 것을 아시죠? (너무나 기본적이므로 머리가 있다면 생각할수 있으므로 생략) 자아 예를 들어봅시다... .DATA MYDATA DB 12,23,15,13,6,23 .CODE MOV SI,OFFSET MYDATA (OFFSET 명령어는 그 데이타가 있는 주소 를 의미하는 지시어입니다... LEA SI,MYDATA 와 똑같습니다...) MOV BX,3 (이건 네번째 데이타를 의미하기 위한거에요..) MOV AX,[SI+BX] 자아 이제 AX 에 어떤 값이 들어갈까요? 예에 바로 13입니다... C 형식으로 표현해볼까요? char mydata[6] = { 12,23,15,13,6,23 }; char i; i = mydata[3]; C 에서 배열과 포인터를 거의 동시에 같이 배우고, 배열과 포인터는 밀접한 관계가 있다 어쩌구 등등을 들어보셨나요? 어셈에서 배열과 포인터는 단순히 주소지정방식의 일부분에 불과합니다... 다른언어에서는 포인터란 계념을 거의 안쓰는 이유와 다른언어와 달리 C에서의 배열은 0 부터 시작하는 이유등에 대해서 짐작이 오시는 분들이 계세요? 네에...아주 똑소리나게 똑똑하시군요... 어셈과 C를 같이 배우신 분들은 아마도 이해될껄? 이제부턴 여담이자 알아두면 좋음직한 내용입니다.. ============================= MOV 명령어의 개수 ????????? ============================= MOV AL,13 이란 명령어를 코딩하고 어셈블 한 다음에 뭐 DEBUG 로 보든지 PCTOOLS 에서 HEX모드로 보시든지, 어째튼지간에 C3 13 (임의로 적은겁니다) 이라는 숫자가 바로 저 명령을 의미한다는걸 찾을 수가 있습니다. 근데 MOV BX,13 이라고 했을때 C3 라는 부분이 바뀌는 걸 볼수가 있어요... 결국 같은 MOV 명령이라고 해도 레지스터에따라, 혹은 주소지정방식에 따라 달라짐을 알수가 있습니다.. 이게 또한 기계어 코딩보다 어셈이 쉬운 한가지 이유가 됩니다. MOV 명령에 해당하는 기계어 코딩은 아마도 20개가 족히 넘을것으로 사료됩니다... 결국 우리가 배우는 어셈 명령어보다 기계어 명령이 많다는걸 짐작하실줄로 믿습니다... 거참... 근디 말이죠...굳이 이렇게 할 필요가 있습니껴? 하고 묻는 분들이 계신다면 내가 또 힘이 있습니까... 설명해야죠... 만약에 레지스터도 번호를 붙이고, MOV 명령을 C3로 고정했다고 봅시다... 그럼 MOV AX,24 라는 명령어를 C3 01 24 00 이렇게 해야돼죠? 원래는 C3 24 00 이렇게만 해도 돼는것을....... 안그래요? 속도면에서 당당한 이익을 위한 거죠...흐흐.... 대체 컴에서 프로그램이 어떠케 돌아가는 것일까라는 의문을 품게되는 여러분들을 위한 자리였어요.. 불만 있으면 말로 하지말고 주먹으로 해결하시죠.. 아웅...썰렁하다... 그럼 오늘은 바빠서 이만...후후.... 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 436번 제 목:[강좌] 어셈초보 -DEBUG 1- 올린이:nowngm (게임제작) 97/11/27 15:29 읽음:632 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 56번 제 목 : [강좌] 어셈초보 -DEBUG 1- 올린이 : timebomb(이시원 ) 96/01/13 06:11 읽음 : 657 관련자료 없음 ----------------------------------------------------------------------------- 어셈강좌가 꽤나 진척이 되어는 있지만 실속은 별로 없었습니다. 왜냐하면 초보들을 대상으로 하는만큼 기초적인 지식에 치중했기 때문이지요... 저의 강좌를 읽으면서 실제로 실험내지는 작성을 하지 못함에 짜증을 느끼실 분들을 휘해 debug 강좌를 어디선가에서 펐던것을 올립니다.. 꽤나 잘 썼더군요...아마도 옆동 prog 동이 아닌가싶네요.. =========================================================================== 제목 : [초급-실습] 프로그램 하나 ( 소스 & 설명 )#1 올린이 : 까망벌레(정태식 ) 94/10/26 00:41 읽음 : 414 관련자료 없음 이제 DEBUG 라는 것으로 간단한 어셈블리어 프로그래밍을 해보겠습니다. 음...DEBUG라는게 과연 어디에 쓰이는 것인지 우선 말하자면, DEBUG 말그대로 버그를 잡은 데에 쓰이는 것입니다. 도스상에서 지원되는 이런 버그잡는거 말고라도 터보 디버그같은 여러가지 유틸리티가 있습니다. 하나하나 단계별로 실행을 시켜가며 과연 무슨 버그가 있나 하고 레지스터나 플래그 등등을 일일이 살펴보며 확인할 수 있는 유틸중의 하나죠.... 헤...혹시 '버그'가 먼지 모르시는 분....을 위해 간단히... 프로그래머가 작성한 프로그램 중에 발생할 수 있는 대표적인 것 중에 ERROR와 WARNING이 있고 또 여기에 가장 골치아픈 버그라는 것이 있지요. 에러가 나면 물론 프로그램 실행이 불가능 하게 되는건 당연 하고요, WARNNING같은 것은 실행하는데 지장은 없지만 자칫 엉뚱한 결과가 출력될수도 있는 위험성을 안고 있을때 생기는 메시지 입니다. 이 두가지(ERROR,WARNNING) 모두는 컴파일러나 링크 ( 컴파일과 링크에 대해서는 다음 기회에...) 시에 알아서 프로그래머에게 알려 줍니다. 하지만 이 놈(버그)은 위의 두가지 와는 달리 어떠한 출력 메시지도 없이 실행이 되지만 엉뚱한 결과가 나오거나 자칫 시스템이 다운 되어 버리는 경우도 있습니다. 이럴때는 귀찮지만 일일이 프로그램 소스를 검사 하던가, 그래도 안되면 이 DEBUG라는 것을 돌려가지구 버그를 잡게 됩니다. (주:여기선 버그를 시멘텍(의미적)인 에러로 국한했는데 제가 알기로는 버그는 신텍스에러(ERROR,WARNING)와 시멘텍에러 두가지를 모두 포함합니다.) 저희 학교 교수님의 예를 들자면, 이분께서 5000라인 가까이 되는 C프로그램을 작성을 했는데 에러나 경고가 전혀 없이 결과값이 엉뚱하게 나오더랍니다. 그래서 그 5000라인 이나 되는 소스를 일일이 검사하고 검사해도 전혀 이상이 없었답니다. 그것을 1주일 동안 꼬박 밤새가며 찾다가 드디어 찾았는데, 그것이 무엇이냐...하믄 if ( i == 0 ) { 이라고 해야 하는 걸 if ( i = 0 ) { 이라고 했다는 것입니다. 그걸 알았을 때의 그 황당함.... 꼬옥 이런걸 버그라고하지는 않습니다만, 이런것도 버그가 될 수 있다는 것이지요. 그럼 다시 원점으로 돌아와서... 아마 여러분들 컴퓨터에는 모두 이 DEBUG라는 것이 있을겁니다. 흐....도스 없이 컴을 사용하시는 분은 없겠지요? 그럼 이 DEBUG를 돌려 봅시다. C:\DOS>debug - 이와 같이 화면에는 '-' 표시가 찍힙니다. 이건 바로 디버그를 사용할 준비가 되었다는 것을 의미 합니다. 그럼 다음과 같이 입력을 해 보세요. ( 대문자는 자동으로 표시되는 것이고, 소문자는 직접 입력을 하는 것입니다. ) (주:이런것을 프롬프트라고 하죠??) -a 0A48:0100 mov ax,0123 0A48:0103 add ax,0025 0A48:0106 mov bx,ax 0A48:0108 add bx,ax 0A48:010A mov cx,bx 0A48:010C sub cx,ax 0A48:010E sub ax,ax 0A48:0110 <--- 여기서는 그냥 엔터만 칩니다. - 그럼 간단한 예제 프로그램 입력을 마쳤습니다. 여기서 한가지, 앞의 숫자 0A48:0100 에서 ':'앞의 0A48은 시스템 마다 다를 수 있습니다. ( '다를 수 있습니다' 가 아니고 아마 10중 8,9는 다를 것입니다 ) 그건 신경쓰지 마시고...... 일단 이들이 맞게 입력이 되었는지 확인을 해 바야겠죠. 그럼 또 다음과 같이... -u100 0A48:0100 B82301 MOV AX,0123 0A48:0103 052500 ADD AX,0025 0A48:0106 89C3 MOV BX,AX 0A48:0108 01C3 ADD BX,AX 0A48:010A 89D9 MOV CX,BX 0A48:010C 29C1 SUB CX,AX 0A48:010E 29C0 SUB AX,AX ........ - ( 바로 위의 '....'은 그 뒤로도 몇가지 비슷한 형태로 주루룩 나온다는 것을 말합니다. 이 부분은 시스템 마다 다른 내용이 출력 되기 때문에 별로 신경쓸 것은 없습니다. 우리가 필요한 부분은 위에 쓴 저 내용뿐입니다. ) 제대로 되었는지요? 잘못되었다고요? 그럼 'Q'로 디버그에서 빠져 나온뒤 다시 시작해 보세요...( 다른 방법이 있긴 하지만 일단은 그렇게 하시기를... ) 사실 위의 프로그램은 실행 시켜도 아무런 결과 없이 시스템만 다운 됩니다. 절대 실행 시키지 마시길....헤헤~~ 그리고 한번 다음과 같이 입력을 해보세요.. -d100 0A48:0100 B8 23 01 05 25 00 89 C3-01 C3 89 D9 29 C1 29 C0 .#..%.......).). 0A48:0110 8B C6 F7 D0 D3 48 DA 2B-D0 .....등등 주루룩~~~ 이렇게 출력이 됩니다. 내용은 다를 수 있지만 첫째줄의 모든 내용은 모두 같습니다. ( 설명은 조금 후에... ) 그럼 이제 본격적으로 위의 프로그램이 과연 제대로 돌아가는지, 또 어떻게 레지스터들이 변하는지 확인을 해 봐야 겠죠? 그럼 일단 프로그램이 실행되기 전의 레지스터들의 상태를 체크해 봅시다. -r AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0A48 ES=0A48 SS=0A48 CS=0A48 IP=0100 NV UP EI PL NZ NA PO NC 0A48:0100 B82301 MOV AX,0123 - 다음과 같이 출력이 될것입니다. 하지만 위에 DS, ES, SS, CS 값들은 모두 컴퓨터 마다 다르게 출력이 될겁니다. 하지만 위의 DS, ES, SS, CS 네개의 값이 모두 동일하다는 것은 어느 PC나 같습니다. 그럼 하나씩 단계적으로 실행을 해 보지요. ( 출력에 대한 설명은 조금 후에 하겠습니다. ) ( '()' 안의 숫자는 실제로는 출력이 되지 않는 내용 입니다. 이 숫자는 설명의 편의상 순서를 정하기 위해 사용 했습니다 ) -t (1) AX=0123 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0A48 ES=0A48 SS=0A48 CS=0A48 IP=0103 NV UP EI PL NZ NA PO NC 0A48:0100 B82301 ADD AX,0025 -t (2) AX=0148 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0A48 ES=0A48 SS=0A48 CS=0A48 IP=0106 NV UP EI PL NZ NA PO NC 0A48:0100 B82301 MOV BX,AX -t (3) AX=0148 BX=0148 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0A48 ES=0A48 SS=0A48 CS=0A48 IP=0108 NV UP EI PL NZ NA PO NC 0A48:0100 B82301 ADD BX,AX -t (4) AX=0148 BX=0290 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0A48 ES=0A48 SS=0A48 CS=0A48 IP=010A NV UP EI PL NZ NA PO NC 0A48:0100 B82301 MOV CX,BX -t (5) AX=0148 BX=0290 CX=0290 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0A48 ES=0A48 SS=0A48 CS=0A48 IP=010C NV UP EI PL NZ NA PO NC 0A48:0100 B82301 SUB CX,AX -t (6) AX=0148 BX=0290 CX=0148 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0A48 ES=0A48 SS=0A48 CS=0A48 IP=010E NV UP EI PL NZ NA PO NC 0A48:0100 B82301 SUB AX,AX -t (7) AX=0000 BX=0290 CX=0148 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0A48 ES=0A48 SS=0A48 CS=0A48 IP=0110 NV UP EI PL NZ NA PO NC 0A48:0100 B82301 MOV AX,SI <-- 이부분은 다를 수 있습니다. - 흐...뭐가 먼지... 정신이 없죠? 그럼 이제 이 결과 값들을 가지고 한번 설명을 해 보겠습니다. 우선 이같이 실행도 안되는 프로그램을 뭐하러 짰는고....라고 생각하신다면, 사실 이 프로그램을 예로 든 이유는 프로그램에 따라서 변하는 레지스터의 값들을 확인해 보기 위해서 입니다. 우선 위에서 보았던 'u'에 대해서 나오는 결과들에 대해 말씀 드리지요... 'u'는 'unassemble'의 약자로 'assemble'의 반대적인 의미를 가집니다. 위에서 보았던 'd'의 결과들과 'u'의 결과들에서 발견할 수 있는 공통점이 있지요? 그건 바로 'u'의 결과중에 보이는 '0A48:0100' 과 ' MOV AX,0123' 사이에 있는 'B82301'이라는 것이 보이죠? 그럼 바로 이 위치에 있는 문자들을 주욱 모아 보면.... B82301 052500 89C3 01C3 89D9 29C1 29C0 와 같은 내용이 됩니다. 그리고 'd'의 결과 값들의 내용을 보면... B8 23 01 05 25 00 89 C3-01 C3 89 D9 29 C1 29 C0 와 같습니다. 어때요? 전자의 내용을 두글자씩 분리해 정리하면 후자의 내용과 꼬옥 들어맞는 것을 알 수 있습니다. 그럼 과연 위의 이상한 숫자와 문자들은 무엇을 의미 할까..... 'd'라는 것은 'Dump'의 약자로 즉, 현재 메모리의 내용을 보여주는 명령입니다. 바로 화면에 주루룩 나오는 내용들이 메모리의 현재 내용이라는 것이지요. 그럼 위의 내용을 분석해 보겠습니다. 일단 'B82301'을 시작해 보죠... 이것은 바로 기계어 코드로 'MOV AX,0123'이라는 명령어를 기계어로 바꾼 것입니다. 그럼 왜 이것을 기계어로 바꾸어야 할까요... 그것을 'MOV AX,0123'이라는 명령어는 PC에서는 전혀 알아 듣지 못하는 내용 입니다. 그래서 이것을 PC에서 알아들을 수 있는 내용으로 바꾸기 위해 위와 같은 기계어 코드를 생성하게 된 것입니다. 어셈블러는 이와 같이 사용자가 입력하여준 어셈블리어 언어를 바로 기계어 코드로 변환 하여 주는 역할을 합니다. 사실 사람이 직접 이 기계어 코드를 사용해서 프로그래밍 한다면 더없이 좋겠지요...하지만....그 기계어 코드를 일일이 다아 왜우는 사람은 아마 없을 겁니다. ( 제가 알기로는 말이죠..흐흐 ) 그래서 좀 더 사용자가 편리하게 프로그래밍을 할 수 있도록 영문으로 되어진 'MOV' 와 같은 명령어를 만들어 내게 된 것입니다. C언어나, 베이직 등등 모든 프로그래밍 언어들이 바로 프로그래머들을 위해 좀 더 편리하게 프로그래밍 할 수 있도록 만들어 졌습니다. 결과적으로 모든 언어는 최종적으로 바로 위와 같은 기계어 코드로 변환을 하게 된다는 것입니다. 다시 'B82301'이라는 것을 뚜러지게 봅시다... ( '뻥~' ) 모두 3바이트로 된 내용 입니다. 'B8' <-- 요것은 과연 어떤 어셈블리어 명령어를 기계어로 변환한 것일까... 답은 간단...'MOV AX' 라는 것을 변환한 기계어 코드 입니다. 하필 'MOV' 가 아니고 'MOV AX' 를 통채로 변환을 했느냐...하시는 분들을 위해 잠시.... 솔직히 'MOV' 따로 'AX'따로 각각 한 바이트의 기계어 코드로 변환을 한다고 하면 알아보기도 쉽고 좋겠죠...하지만 여기에 하나 단점이 발생합니다. 만약 'MOV' 가 기계어 코드로 'C3' 이라고 하고 'AX'는 '25' 라고 칩시다 그럼 'MOV AX'라는 것을 기계어 코드로 바꾸게 되면 결과적으로 C325 라는 결과가 되겠지요? 과연..... 'B8'이라는 코드가 'C325'라는 코드로 변환이 됨에 있어서 원래는 1바이트 만으로 되었던 것이 2바이트로 늘어나 버렸습니다. 이건 쓸데 없는 메모리 낭비만 가져올 뿐입니다. 혹시나 왜, 'MOV' 를 'C' 라는 것으로 하고 'AX'를 '2' 라고 한다면 역시 같은 1바으트로 변환이 가능하지 않냐고 하실 분이 계실 지도 모릅니다. 제 대답은 '벌러덩~' 입니다. 왜냐하면 전에도 말씀 드렸듯이 모든 PC에서 수행되는 기본 단위는 바이트 단위라고 했습니다. 그러므로 'C'라는 것은 완전한 하나의 바이트가 되질 못하기 때문에 처리를 할 수 없게 됩니다. 그럼 혹시 'MOV BX' 같은 것은 또 다른 1바이트의 기계어 코드가 있느냐.. 라는 질문에 '예' 입니다. 그럼 그 많은 명령어와 레지스터들의 조합들을 이렇게 따로따로 코드를 정한다면 1바이트 가지고는 부족하게 되는건 아닌지.. 하지만 걱정 마세요... 1바이트로 안된다면 2바이트를 써서 하면 되는 거니까.. 메모리 낭비? 하지만 일단은 프로그램이 제대로 도라가는게 중요하자나요.. 가급적이면 PC에서 메모리를 적게 먹는 방향으로 설계되었을 줄로 압니다. 됐지요? 이제 뒤의 '2301' 에 대해 말씀 드리지요. 이건 가만히 살펴보면 입력하는 데이터 값인 '0123' 과 숫자는 모두 같은데, 대신 순서가 바뀌었다는 것을 알 수 있습니다. 즉 '01' 과 '23' 각각 1바이트의 내용이 서로 자리바꿈을 했음을 알 수 있습니다. 이 이유는 메모리 구조상 원래 이렇게 저장이 되어지도록 됴습니다. 그 '이유'라는 것은 다음으로 넘기기로 하지요...히힛~~ 어쨋든 '2301'은 AX레지스터에 넣을 값을 알려주는 것입니다. 휴~~~ 일단 1행은 마쳤습니다. 역시 다음 행들 또한 같은 맥락으로 이해 하시면 되고요...주루룩~~~ 왜 어셈블리어 명령어에 대한 설명은 안하냐고요? 후후...이 프로그램을 해보는 목적은 명령어 익히기가 아니구여 바로 메모리의 실제 모습과 레지스터들을 이해하기 위해 해 보는 것이여요.. 이제 'd'라는 명령으로 나오는 출력값들이 무엇을 의미 하는지 알겠죠? 바로 프로그램을 기계어 코드로 바꾸어서 메모리로 저장 시킨 모양을 알려주는 것입니다. 그럼 'd'로 나오는 출력들 중에 왼쪽의 숫자 '0A48:0100' 같은 것들은 무엇을 의미 할까요... 이것들은 바로 메모리의 주소값을 표시해 주는 것입니다. 왼쪽이 세그먼트가 되고 오른쪽이 오프셋이 되는 것입니다. 그리고 제일 오른쪽의 알 수 없는 문자들은 무엇인가 하믄... 변환된 기계어 코드는 어디까지나 그냥 숫자들 입니다. 이 숫자들은 전에 말씀드렸던 아스키 코드로 1바이트씩 표시해 준 것입니다. '23' 같은 것은(16진수) 아스키 코드표를 찾아보면 '#'로 정해져 있습니다. 나머지 들도 마찬가지구요. 그리고 '.'이 상당히 많은데, 이것들은 표준 아스키 코드 이외의 확장 아스키 코드들을 그냥 모두'.' 로 표시한 것입니다. 다음에는 'r' 과 't' 로 나오는 출력들을 가지고 설명을 드리겠습니다. 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 437번 제 목:[강좌] 어셈초보 -DEBUG 2- 올린이:nowngm (게임제작) 97/11/27 15:32 읽음:630 E[7m관련자료 있음(TL)E[0m ----------------------------------------------------------------------------- 『게임 제작 강좌-프로그래밍 강좌 (go NGM)』 59번 제 목 : [강좌] 어셈초보 -DEBUG 2- 올린이 : timebomb(이시원 ) 96/01/14 03:23 읽음 : 639 관련자료 없음 ----------------------------------------------------------------------------- ======================================================================== 제목 : [초급-실습] 프로그램 하나 ( 소스 & 설명 )#2 올린이 : 까망벌레(정태식 ) 94/10/29 20:06 읽음 : 313 관련자료 없음 후.....넘 늦게 올려서 죄송 합니다. 그럼 다시 그 소스를 가지고 설명을 계속 하겠습니다. 이번에는 'r' 명령과 't'명령에 대해 설명한다고 했지요? 그럼 해보겠습니다. 우선 데이타, 스텍, 코드 세그먼트에 대해 설명을 해 드리겠습니다. 여러분도 보시다 시피 소스에서 입력하여준 명령어들 'mov, add, sub'등등 이것들도 우선은 메모리에 저장되어 지는것을 보았지요? 이와 같이 PC에 어떠한 연산 명령을 내려 주는 것들을 저장하는 메모리 영역을 코드 세그먼트라고 부릅니다. 말그대로 메인 프로그램 이라고나 할까요. 전에 말씀드렸다 시피 메모리 구조는 세그먼트와 오프셋으로 구성되어 진다고 했습니다. 그럼 과연 한 세그먼트의 크기는 얼마나 될까요? 그것은 오프셋의 크기와 관련이 됩니다. 다음과 같은 경우를 생각해 보지요. 만약 메모리에 'abcdefg'라고 차례대로 저장을 시킨다고 해 봅시다. 그럼 이것들이 과연 메모리에 어떠한 모양으로 저장이 되어지는지 아시겠지요? ;-------------------------------- ; a ; b ; c ; d ; e ; f ; g ; ; ;-------------------------------- 다음과 같습니다. 여기서 만약 'a'라는 문자가 저장된 곳이 바로 0123:53F2 라고 가정을 해 봅시다 그럼 세그먼트는 '0123'이 되고 오프셋은 '53F2' 라고 할 수 있습니다. 그럼 'b'가 저장된 곳은 주소가 어떻게 될까요... 그건 '0123:53F3'으로 세그먼트가 아닌 오프셋이 하나 증가한 메모리 주소를 갖습니다. 'c'역시 차례대로 '0123:53TF4'가 되는건 예측할 수 있죠. 이와 같이 하나의 세그먼트에는 오프셋의 범위가 '0000' 부터 'FFFF' 까지 됩니다. 그러므로 바로 오프셋의 범위가 하나의 세그먼트의 크기라고 할 수 있는 것입니다. 이걸 계산해 보면 약 64K 바이트의 메모리가 됩니다. 정의해서, 하나의 세그먼트 크기는 64K의 용량을 갖는다는 것을 알 수 있습니다. 그래서 이 세그먼트 내에 이 코드들이 들어간다는 것이지요. 그럼 1메가의 메모리에는 과연 몇개의 세그먼트가 존재 할 수 있는지 계산해 보죠. 1 메가면 1024K바이트라는 것은 알고 있습니다. 그럼 계산은 간단. 1024 / 64 = 64 라는걸 알 수 있습니다. 그러므로 '1메가의 메모리 안에는 64개의 64K바이트를 같은 세그먼트가 존재 한다.' 라고 할 수 있습니다. 그럼 이와 같이 세그먼트들을 나누는데 있어서 왜 데이타 라느니, 코드라느니 이런것들을 나누느냐, 라는 질문에 만약 프로그램이 메모리에 저장되어지는데 있어서 그 크기가 64K를 넘어간다고 생각해 보세요. 그럼 이것을 어떻게 처리해야 하느냐.... 물론 두개의 세그먼트를 사용하면 되겠지요. 그럼 이 두개의 세그먼트를 어떻게 사용해야 효율적일까요? 보통 만약 두개의 세그먼트를 사용한다고 하면, 전에 예를 들었던 '3+4'에서 '3'과 '4'는 데이터 라고 했고 '+'는 연산 명령이라고 했지요? 이와 같은 덧셈을 1000개 수행해야 한다고 해 보세요. 덧셈인데, 수 많은 데이터 들을 일일이 다아 더하는 명령을 주어도 되지만 데이타 영역을 따로 만들어 주고, 여기에 이 데이터 영역에 있는 값들을 꺼내다가 계산한다면, 훨씬 효율적이 될 수 있습니다. 여기서 데이터 영역이 저장되어지는 세그먼트를 데이타 세그먼트(Data Segment) 라고 부르고 바로 연산 명령 같은 것이 저장되어지는 세그먼트를 코드 세그먼트 (Code Segment) 라고 부릅니다. 물론 이 두가지(데이타, 연산명령) 를 하나의 세그먼트 안에 넣어 주어도 됩니다. 그리고 위의 내용에선 분명 스텍 세그먼트(Stack Segment) 라는것이 있다고 했습 니다. 이 스텍이라는 것은 나중에 설명을 드리겠습니다. 그럼 대충 세그먼트라는 것에 대해 이해가 가셨을 줄로 믿습니다. 그럼 이제 IP ( Instruction Pointer ) 가 무엇인지 설명을 또 드리죠.. PC 상의 레지스터 상태를 보여주는 'r'명령을 내려 보면 알 수 있듯이 모든 레지스터의 저장된 값들이 나옵니다. 거기에 보면 'IP'라는 것이 있습니다. 이것은 보통 초기에는 '100'이라고 나옵니다. 이것은 오프셋 값을 나타낸 것으로, 무엇의 오프셋이냐 하믄, 여러분이 직접 넣어준 프로그램을 'u'명령으로 보면 'MOV AX,0123'이라는 프로그램이 바로 오프셋 100에 저장이 되어 있다고 나옵니다. 그럼 'IP'와 프로그램의 가장 선두 부분의 오프셋 값이 같다는 것을 알 수 있죠. 또 'r' 명령후 나오는 값들중에 제일 마지막 부분에 ' MOV AX,0123'이라고 써 있는 부분이 있죠.. 그것은 지금 상태에서 프로그램을 실행시키면, 다음으로 실행이 되어지는 프로그램을 나타내는 것입니다. 이제 't'명령을 실행시켜 보면 ( 't' 는 'Trace'의 약자로 프로그램을 하나씩 단독적으로 실행시켜 나가면서 레지스터의 상태를 확인해 볼 수 있습니다 ) 일단은 'MOV AX,0123'이라는 것을 실행 시킵니다. 그럼 다음으로 실행시키는 명령이 'ADD AX,0025'라고 표시해 줍니다. (표시된 것은 실행시킨 프로그램이 아닌 앞으로 실행된 프로그램이라는 것을 나타냅니다 ) 그럼 이때까지 't'를 한번 해 주었습니다. 소스에서 보면 (1)번에 해당하는 내용 입니다. 그럼 여기서 이제 'IP'값을 보세요. 변했죠? 증가했음을 알 수 있습니다. 그럼 얼마나 증가를 했습니까? 'MOV AX,0123'이 차지하는 메모리는 3바이트라고 했습니다 그리고 그 다음 명령행이 저장되어진 메모리 주소는 'MOV AX,0123'이 저장되어진 오프셋 값에 바로 이 크기인 3바이트 증가한 '103'이라는 것을 알 수 있습니다. 다시 말해 'ADD AX,0025'라는 명령이 저장되어진 메모리 주소가 '103'부터 시작된 다는 것을 알 수 있습니다. 그럼 'IP'레지스터의 '103'과 값이 같지요... (2) 번 (3) 번 모두 그 'IP'레지스터의 값과 지금까지 실행하고 다음으로 실행되 어질 메모리의 오프셋 값이 동일하다는 것을 알 수 있습니다. 여기서 보듯이 'IP'라는 레지스터는 프로그램 소스를 실행 시키는데 있어서 프로세서 (CPU) 가 과연 그 많은 메모리 중에 어떤곳에 실행시켜야 될 프로그램들이 있는지 프로세서에 알려 주어야 합니다. 그것을 알아야 프로그램이 실행이 되어지지요. 그럼 과연 프로세서가 어느것을 보구서 메모리의 어떤 부분에 실행되어질 프로그램이 있는지 알 수 있을까요? 그것은 'CS'레지스터에 저장되어진 값으로 프로그램이 들어 있는 세그먼트를 알아내고 'IP'레지스터에 저장되어진 값으로 프로그램이 들어있는 메모리의 오프셋 값을 알아 냅니다. 그럼 프로그램을 한 라인 실행시키면 그 명령을 수행하고 다시 프로세서는 'CS'값과 'IP'값을 확인 해 보고, 그 다음 명령를 수행하게 됩니다. 예를 들어 보죠. 전의 소스를 보면서.... 'IP' 가 100인 상태, 그리고 'CS'가 '0A48', 에서 세그먼트 '0A48' 오프셋 100번지에 있는 'MOV AX,0123'을 실행하게 됩니다. 그럼 다시 그 다음 명령인 'ADD AX,0025'를 실행시키기 위해선 'IP'값이 3바이트 증가된 '103'이 되어야 합니다. 그것은 사용자가 할 필요 없이 PC가 알아서 해 줍니다. 그럼 프로세서는 그 두가지의 레지스터를 확인해 보고 다음으로 실행시켜야 하는 명령을 수행하게 됩니다. 그래서 'CS'와 'IP' 가 항상 짝을 이룬다는 말을 하게 됩니다. 데이타 세그먼트 또한 마찬가지 입니다. 그 예는 다음 프로그램 소스에서 알아보도록 하겠습니다. 그리고 프로그램 모델이라는 것이 있습니다. 'small' 'compact' 'large' 'huge' 등등의 모델들이 있습니다. ======================================================================== DEBUG 의 내용은 여기까지입니다... 여러분들이 PUSH 나 POP 혹은 여타 책에서 볼수 있는 명령어들을 가지고 실험해보세요... 직접 피부로 느끼실수 있으리라 봅니다.. DEBUG 는 이것만이 전부는 아닙니다.. DEBUG 내에서 쓰이는 명령어 요약등을 보시고 실행하면서 익혀야 합니다. 그럼 즐거운 공부가 되시길 빕니다..