크리에이티브 커먼즈 라이센스

홈페이지HOME

PHP

JavaScript

HTML

CSS

드롭다운메뉴

제로보드4

도   움   말

백지 건강강좌/자가임상체험

물박사(자가면역질환...)^미러

전동명(천연물질사전)^미러

竹田 장승옥(블로그)^글목록

계산환산(계산기)^ 단위변환

관주성경 TTS 일반파일 TTS

바이블로 Bible_ro 다운로드

다운로드>폰에 복사
>파일선택...설치됩니다.

[도움말 보기] 바로가기

개선 요구, 충고는
아래 관리자 연락
전화/메일 부탁 드립니다.
최대한 빨리 처리하고
업데이트 올리겠습니다.

이 글은 1994. 8.월초(?)경부터 하이텔에 올렸던 자료이다.

하이텔에 들어가 보니 일부 없어진 것이 있는데, 다행히 내 컴퓨터에서 찾았다.

asm_01.(레지스터)

프로그래밍 언어도 하나의 언어입니다.

언어란 하나의 약속입니다.

우리가 약속을 모를 때 우리는 전혀 무능한 사람입니다.

그러나 일단 약속을 알고 나면 우리는 유능한 사람이 됩니다.

우리는 외국 사람들과 대화하기 위하여, 그 외국 사람들 사이의 약속인 해당 외국어를 열심히 배웁니다.

프로그래밍 언어를 배우는 것은 확실히 그보다 쉽습니다.

필자도 프로그래밍 전문가가 결코 아니며, 오히려 입문하는 중입니다.

필자가 감히 글을 쓰는 것을 보고, 부담 없이 따라 오시기 바랍니다.

디버그는 프로그램밍 언어 패키지를 구입하지 않아도, 도스만 있으면 누구나 사용할 수 있는 도구입니다.

우선 디버그(디버거, 도스의 debug.exe)로 시작합시다.

제 01 장  레지스터

앞 장에서 우리는 디버그를 시작하고 끝내는 방법을 배웠다.

그리고 디버그 안에서 간단한 프로그램을 만들고, 그 프로그램을 역시 디버그 안에서 g <번지> 명령으로 실행해 보기도 했다.

아주 짧은 내용이었지만, 실행 과정에 필요한 많은 내용을 익혔다.

그러나 부담을 느끼지 않기 위해, 주로 이론적인 많은 설명을 생략하였다.

우리가 일단 피하고 넘어 온 이론적인 부분 중 반드시 알아야 될 것도 있다.

그 최소한의 내용을 이 장에서 쉽게 풀어서 이해하기로 한다.

    ## 필자통신

필자는 중학생 시절에 어느 교수님의 학습 방법을 설명한 책을 읽은 적이 있다.  사람의 기억은 시간이 지날수록 되살리기 어려워지는데(이것은 누구나 아는 사실이지만), 따라서 한 번 본 후 가능하면 즉시 다시 복습하는 것이 효과적이다.  30 분(?, 오래 되어서 기억이 희미함) 이내에 최초의 복습을 하는 것이 좋다.  일단 그 시간 안에 최초 복습을 하면, 기억이 며칠까지는 확실하게 남는다.

그러나 역시 그 기억도 희미해지므로, 며칠 이내에 재차 복습을 한다.

대개 그런 내용이었던 것으로 필자는 기억한다.

제 00 절  복습(제 00 장)

디버그란 도스의 debug.exe 파일 또는 도스 버전에 따라 debug.com 파일의 이름을 따서 부르는 말이다.

디버깅 작업에 사용되는 도구가 도스의 디버그 프로그램이다.

우리가 디버그를 이용하여 기계어를 조금이나마 공부하려는 목적은 컴퓨터의 기계적인 작동에 대한 이해를 얻기 위함이다.

디버그를 시작하려면 도스상에서 debug와 같이 명령한다.

명령 파일 이름만 입력해서 그 명령을 어디서나 실행하려면, 그 파일이 저장된 방의 경로(c:\dos; 등)이 autoexec.bat 파일의 path에 들어 있어야 된다.

디버거를 실행하면, 하이픈(-) 모양의 디버그 프롬프트가 나타난다.

디버그를 끝내고 도스로 나가려면 디버그 프롬프트에서 q한다.

디버그 프롬프트에서 디버그 명령 설명을 보려면 ?로 명령하면 된다.

문자 $의 코드값 16진수 24를 dl에 저장하는 명령은 mov dl,24이다.

ah에 16진수 2를 저장하고, int 21 명령을 실행하면 dl에 저장해 둔 16진수의코드값에 해당되는 아스키 문자를 모니터 화면에 표시해 준다.

디버그 프로그램에서 프로그램을 끝내려면 int 20로 명령하면 된다.

????:????와 같은 메모리 번지의 왼쪽 ????는 어떻게 보이든 무관하다.

프로그램을 106 번지 직전까지만 실행하려면 g 106와 같이 명령한다.

디버그 프롬프트에서 q하면 디버그를 끝내고 도스 프롬프트로 나간다.

    ## 필자통신

이 장의 내용은 초보자에게 약간은 부담이 될 수도 있을 것이다.

그러나, 무한정 길게만 쓰는 것도 능사가 아니므로 진행 순서상 부득이 설명한다.  만약 머리가 아파서 진통제 생각이 나면, 소설 읽듯이 한 번만 읽고 잊어 버리라.

잊어 버려도 되는 이유는, 나중에 조금씩 반복해서 나오기 때문이다.

제 01 절  레지스터 입문

디버그의 명령은 대개 레지스터라는 것을 중심으로 이루어진다.

그러므로, 레지스터에 대한 기본적인 이해를 확실히 해 두면 도움이 된다.

디버그를 실행하고 화면을 확인하면서 공부하면 쉬울 것이다.

    ## 필자통신

이하 한 부분에서 관련되는 지식을, 예를 들어서 워드라는 용어를 설명하는 자리에서 바이트를, 한꺼번에 설명하는 일은 되도록 피할 것이다.  언어를 약간 공부한 경험이 있다면 그런 설명을 왜 하지 않는가 하고 생각할 수도 있겠지만, 초보자에게는 오리려 부담만 줄 뿐이다.

쉽게 부담없이 익히는 것이 지름길이라고 생각한다.

레지스터의 내용을 확인하려면 r 명령으로 가능하다.

먼저 디버그를 시작해야 된다.

    ...> debug

    - r

    AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000

    DS=0BDB ES=0BDB SS=0BDB CS=0BDB IP=0100 NV UP EI PL NZ NA PO NC

    OBDB:0100   0F         DB      OF

    -

위의 화면은 필자의 컴퓨터에서 나타난 것일 뿐이다.

사용자의 컴퓨터에서는 위와 같은 내용, 다른 내용이 나타날 수 있다.

다른 내용이래야 = 오른쪽의 4 자리 16진수가 다를 뿐이다.

우리의 r 명령에 대해, 디버그가 보고한 3 줄 중 첫줄은 일정하다.

그러나 그 보고서의 2, 3 줄은 컴퓨터와 메모리 상태에 따라 달라질 수 있다.

화면만 보면 어렵게 느껴지겠지만, 그렇지 않다.

하나씩 차근차근 살펴 보기로 하자.

1.  레지스터 대략 파악

보고서를 옮겨 두고 모양을 잘 살펴 보면 무언가 보일 것이다.

구체적인 내용을 익히기 전에 모양의 윤곽을 보아 두는 것은 도움이 된다.

1) 보고서 첫 줄

    AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000

우선 첫줄의 다른 모든 레지스터 값은 0000으로 동일하며, 다만 SP 레지스터만이 FFEE라는 값을 가지고 있음을 알 수 있을 것이다.

2) 보고서 둘째 줄과 셋째 줄

    DS=0BDB ES=0BDB SS=0BDB CS=0BDB IP=0100 NV UP EI PL NZ NA PO NC

    OBDB:0100 0F           DB      OF

둘째 줄과 셋째 줄에서는 두 가지를 눈여겨 보기로 하자.

먼저, 둘째 줄에는 0BDB(0bdb)라는 수가 DS, ES, SS, CS라는 4 개의 레지스터 값으로 보이며, 동시에 같은 값이 셋째 줄의 첫부분에도 나와 있다.

디버그를 처음 시작하여 레지스터 명령(r)을 하면 IP 레지스터의 값은 언제나 0100으로 나타나게 되어 있다.

사실은 셋째 줄의 0BDB(0bdb)라는 값은 CS 레지스터의 값을 표시한다.

그 사실은 나중에 디버그를 실습하다 보면 확실하게 이해할 것이다.

그 다음으로 둘째 줄 IP 레지스터의 값 0100이 셋째 줄에도 나와 있다.

따라서 셋째 줄에 보이는 콜론(:) 좌우의 4 자리 16진수는 :을 나타낸다는 사실을 알 수 있다.

이 두 가지 사실은 기억해 둘 가치가 있는 것이다.

CS:IP는 현재의 메모리 번지를 나타내는 것이다.

메모리 번지에 관해서는 뒤에 가서 자세히 설명하기로 한다.

3) 기계어와 번역

지금 너무 깊이 설명하면 어렵게만 느껴질 것이다.

그러나, 조금만 더 보고 넘어가자.

셋째 줄에는 콜론(:) 좌우에 4 자리 16진수가 있고, 그 오른쪽에는 16진수 3 쌍이 보이는데, 처음 쌍과 나머지 두 쌍은 한 탭 간격 떨어져 보인다.

셋째 줄의 OBDB:0100는 디버그가 현재 다룰 수 있는 메모리 번지를 나타내는 것이며, 그 오른쪽에 붙어 있는 0F는 그 번지에 저장되어 있는 16진수 값이다.

그 오른쪽으로 두어 탭 간격 떨어져 나오는 DB 0F(db 0f)는 현재 메모리에 저장되어 있는 하나의 명령어이다.

앞의 16진수 0F는 컴퓨터가 알아 보는 기계어이며, 뒤의 16진수 2 쌍인 DB 0F는 그 기계어를 우리가 알아 볼 수 있는 어셈블리어로 번역한 것이다.

## 활용 팁

레지스터 이름이나 명령어에는 영문자 o가 들어갈 수 있지만, 수를 나타내는 16진수 값에는 영문자 o가 들어갈 수 없다.  지금까지 설명하면서 화면에 보이는 대문자 뒤에 괄호를 치고 소문자로 바꾸어 적어 보였떤 이유도 처음 공부하는 분들의 혼동을 예방하기 위함이었다.

앞으로는 그렇게 덧붙이지 않더라도 알아 볼 것으로 믿는다.

16진수의 각 자리를 구성하는 숫자는 다음에 보이는 것 뿐이다.

    1, 2, 3, 4, 5, 6, 7, 8, 9, a(10), b(11), c, d, e, f(15)

만약 10진수로 16을 16진수로 표시하려면 10h가 된다.

뒤에 붙인 h는 그 수가 16진수임을 나타내 준다.

    ## 주의

설명에서 16진수 뒤에 붙이는 h라는 것은 우리가 구별하기 쉽도록 사용하는 것일 뿐, 디버그를 실행하여 보이는 화면에는 나타나지 않는다.

뿐만 아니라 우리가 디버그에서 입력할 때도 h를 붙여서는 안 된다.

4) 수를 세는 방법

10진수 2진수 16진수 등의 진법에 익숙하지 않은 분들을 위해 설명한다.

바닷가에서 조약돌을 한 번에 한 개씩만 주워 바구니에 담아 보자.

한 번 담을 때마다 바구니의 조약돌을 한 개씩 많아질 것이다.

이렇게 많아지는 과정에 바구니에 몇 개가 들어 있는지를 표시해 보자.

그 표시를 누가 하느냐에 따라 달라진다.

물론, 시작은 0으로 마찬가지이다.

    사  람:0, 1,  2,  3,   4,   5,   6,  7,   8,9,10,11,12,13,14,15,16

    컴퓨터:0, 1, 10, 11, 100, 101, 110, 111, 1000, ...

    16진수:0, 1,  2,  3,   4,  5,   6,   7,   8,9, a, b, c, d, e, f,10

사람은 십진법을 사용하므로 10 이상을 표시하는 숫자는 없다.

컴퓨터는 이진법을 사용하므로 2 이상을 표시하는 숫자는 없다.

16진수는 십육진법을 사용하므로 16 이상을 표시하는 숫자는 없다.

    ## 필자통신

'이상'이란 말은 '같거나 크다'는 뜻이다.

'숫자'란 한 글자(자리)로 수의 크기를 나타내는 것이다.

즉 10이라는 수는 1이라는 숫자와 0이라는 숫자로 구성된 것이다.

따라서, 십진법에서 10을 나타내는 숫자(한 자리의 수 표시)는 없다.

2.  레지스터의 실체

레지스터 전체의 외모를 대충 살펴 보았으니, 이제 그 속을 들여다 보자.

먼저 레지스터란 무엇인가를 대략 알아 보고, 다음으로 종류와 용법을 살피자.

1) 레지스터의 용도

레지스터란 고급 언어의 변수와 비슷하게 쓰이는 것이다.

변수란 어떤 값이든지 담아 둘 수 있는 그릇이다.

그와 같이 레지스터에도 어떤 값을 담아 둘 수 있다.

변수가 그러하듯이, 레지스터에도 새로운 값을 담으면 이전 값은 사라진다.

레지스터에 담아 두는 값은 어떤 명령어를 뜻할 수도 있고, 어떤 명령을 실행하는 데 있어서 실행 대상이 되는 파라미터를 뜻할 수도 있다.

    ## 주의

변수는 수가 아니라 수를 담는 그릇이다.

그릇은 물이나 음식이 담길 수 있는 위치와 공간을 제공한다.

마찬가지로 변수는 어떤 수(값)를 담을 수 있는 공간을 제공해 준다.

우리가 xcopy %1 b:\ /v라는 명령을 xb.bat라는 배치파일로 만들면 우리가 xb t.hwp할 때는 xcopy t.hwp b:\ /v가 실행되며 우리가 xb z.txt하면 xcopy z.txt b:\ /v가 실행된다.

그와 마찬가지로 변수에는 우리가 필요한 대로 임의의 값을 얼마든지 바꾸어 담을 수 있는 것이다.

다만 그릇의 크기에 따라 담을 수 있는 음식의 양이 결정되듯이, 변수도 그것의 크기에 따라 담을 수 있는 값의 크기에는 한계가 생긴다.

레지스터도 그와 비슷하게 생각하면 된다.

2) 레지스터와 메모리

레지스터는 메모리 즉 램과는 다르다.

다시 말해서 레지스터는 메모리의 일부가 아니라는 말이다.

메모리는 기본 640 KB 뿐 아니라 확장 메모리도 사용 가능하지만, 레지스터는 일정한 갯수로 한정되어 있으며, 그 수효가 얼마 되지 않는다.

수가 얼마 되지 않으므로, 차분히 살펴 보면 어려울 것이 하나도 없다.

3) 범용 레지스터(general-purpose resister)

문자 그대로 우리가 일반적으로 값을 담아 두고 변경할 수 있는 레지스터이다.

범용 레지스터는 AX, BX, CX, DX의 4 개가 있다.

레지스터의 이름 뒤에 등호(=)에 붙어 나오는 4 자리 수는 16진수이다.

16진수 4 자리 크기의 수를 워드라고 부른다.

각 레지스터는 워드 즉 16진수 4자리를 저장할 수 있는 크기임을 알 수 있다.

4) 기타 레지스터

나머지 레지스터들은 특수한 목적에 사용된다.

그 자세한 내용은 그 레지스터들을 하나씩 써 보면 자연히 알게 된다.

그 일은 차츰 하기로 하자.  급히 먹는 밥은 체할 우려가 있기 때문이다.

우선 앞에서 본 CS 레지스터와 IP 레지스터를 각별히 기억하자.

그 두 레지스터로써 우리가 지금 사용하는 메모리 번지를 표시하기 때문이다.

그 구체적인 내용은 절을 바꾸어 메모리에 관한 설명에서 보기로 한다.

    ## 필자통신

노파심에서 다시 한 번 알린다.  이론적인 설명은 한 번 읽고 완전히 이해하기 어렵다.  또한 페이지마다 완전하게 이해하고 넘어가려고 붙들고 늘어진다고 해결되지도 않는다.  이론적인 설명은 어느 정도 이해하고, 거의 이해되지 않더라도, 화면을 소개하면서 이렇게 실행하라고 안내하는 내용만 철저하게 소화하고 넘어가다 보면 다 알게 된다.

공부하는 방법을 잘 선택하면 성공하고, 그러지 못하면 실패한다.

제 02 절  메모리 번지

우리가 디버그를 실행하여 프로그램을 만들 때, 한 편으로는 레지스터를 사용하고 다른 한 편으로는 메모리를 이용하여 프로그램을 짜게 된다.

따라서 레지스터와 함께 메모리에 관해서도 약간은 이해할 필요가 있다.

1.  8088이 다룰 수 있는 가장 큰 수

8088 계열(8088, 80286, ...)의 컴퓨터(사실은 마이크로 프로세서)에서 기본적으로 표시할 수 있는 수의 최대값은 16진수 4 자리(워드)이다.

그 크기가 얼마나 되는지 계산해 보자.

16진수의 각 자리에서 가장 큰 숫자는 F(10진수의 15에 해당)이다.

따라서 16진수 4 자리로 표시할 수 있는 가장 큰 수는 FFFF가 될 것이다.

이것을 10진수로 바꾸면 어떻게 되는지 계산해 보자.

        3 자리  2 자리  1 자리  0 자리  10진수

                                F           15

                        F                  240 = 15 * 16

                F                         3840 = 15 * (16 *16)

        F                                61440 = 15 * (16 * 16 * 16)

        ----------------------------------------

                                         65535

10진수로 65535가 8088이 표시할 수 있는 최대값의 수치가 된다.

진수 변환 방법은 위의 계산표를 보면 어느 정도 이해할 것이다.

어렵게 생각된다면 몰라도 무관하다.  나중에 설명할 때가 있을 것이다.

가장 작은 수 0에서부터 가장 큰 수 65535까지 수의 갯수는 65536이 된다.

2.  세그먼트와 오프셋

초보자라도 65536이라는 수는 어디선가 많이 보았을 것이다.

메모리의 크기를 계산할 때 바이트(byte), 킬로 바이트(KB), 메가 바이트(MB)라는 단위를 사용하는 것은 누구나 알고 있을 것이다.

물론 우리가 여기서 다루는 것은 바이트가 아니라 비트이다.

그러나 그 문제가 아니라, 컴퓨터에서 K(킬로)란 1,000 배가 아니라 1,024 배를 가리키며 M(메가)란 1,000,000 배가 아니라 1,048,576 배(1024 * 1024 배)이다.

8088은 메모리를 세그먼트(segment)라고 하는 단위로 분할하여 사용한다.

세그먼트 하나의 크기는 16진수로 0h로부터 FFFFh(10진수 65535)까지 즉 64 K까지 차례로 증가하는 숫자를 레이블(이름)로 사용한다.

세그먼트의 레이블(이름)을 표시하는 레지스터가 CS 레지스터이다.

따라서, 하나의 CS 레이블이 표시하고 있는 메모리 구역 내에서 특정 메모리의 상대적인 주소를 표시하는 것이 바로 IP 레지스터라는 것이다.

IP 레지스터가 표시하는 메모리 번지를 오프셋(offset)이라고 한다.

결국 메모리의 번지는 CS 레지스터에 저장되어 있는 세그먼트 번지와 IP 레지스터에 저장되어 있는 오프셋 번지의 조합으로 표시할 수 있다는 결론이다.

다시 디버그를 실행하고 r 명령을 해 보자.

    ...> debug

    - r

    AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000

    DS=0BDB ES=0BDB SS=0BDB CS=0BDB IP=0100 NV UP EI PL NZ NA PO NC

    OBDB:0100   0F         DB      OF

    -

디버그의 보고서 셋째 줄 첫 부분에 나오는 OBDB:0100가 메모리 번지이다.

앞에서 CS 레지스터와 IP 레지스터를 기억해 두자고 말한 바 있다.

콜론(:) 앞이 CS 레지스터에 저장된 값으로 표시되는 세그먼트 번지이고, 콜론 뒤에는 IP 레지스터에 저장된 값으로 표시되는 오프셋 번지이다.

노턴 유틸리티나 피씨 툴즈 등에 포함된 디스크 에디트 프로그램을 실행한 경우에 각 줄의 왼쪽에 8자리로 된 수치를 보았을 것이다.

그 앞의 4 자리는 세그먼트 번지를, 뒤의 4 자리는 오프셋 번지를 나타낸다.

실제로 우리가 디버그를 이용한 프로그래밍을 공부하면서 세그먼트 번지에 관해서는 별 신경쓸 일이 없으며, 오프셋 번지를 집중적으로 다루게 될 것이다.

메모리 번지를 왜 그런 형식으로 표시하는가 하는 문제는 뒤에 가서 설명한다.

지금은 그 정도만 이해하고 넘어가자.

ID:
PW:

     0 분
     2 분

자유게시판

건강백과 HOME

홈페이지 HOME

조   약     HOME

생활지혜 HOME

서식양식 HOME

법원 전산양식 검색

In Na zum

비공개 HOME

백과넷 포탈 : 건강/법률(메인)/홈피/서식/조약/생활지혜

◁ 2002.9.1.~2021.4.11. ▷

관리자 연락(저작권 의심 신고) : 김병희 010-6204-4973 k8z7@hanmail.net