명령의 어셈블리 언어입니다. 초록: 개요: 서문

MIRZO ULUGBEK의 이름을 딴 우즈베키스탄 국립대학교

컴퓨터 기술 학부

주제: EXE 파일의 의미 분석.

완전한:

타슈켄트 2003.

머리말.

어셈블리 언어 및 명령 구조.

EXE 파일 구조(의미론적 분석).

COM 파일 구조.

바이러스의 행동과 확산의 원리.

디스어셈블러.

프로그램들.

머리말

프로그래머의 직업은 놀랍고 독특합니다. 오늘날 과학이 없는 삶과 과학은 상상할 수 없습니다. 최신 기술. 인간 활동과 관련된 모든 것은 없이는 이루어질 수 없습니다. 컴퓨터 기술. 그리고 이것은 높은 발전과 완성도에 기여합니다. 개인용 컴퓨터의 개발이 시작된 것은 그리 오래되지 않았지만, 이 기간 동안 소프트웨어 제품 등에서는 엄청난 발전이 이루어졌습니다. 오랫동안이 제품들은 널리 사용될 것입니다. 컴퓨터 관련 지식 분야는 그에 상응하는 기술과 마찬가지로 폭발적으로 성장했습니다. 상업적인 측면을 고려하지 않으면 이 지역의 낯선 사람들이 전문적인 활동아니요. 많은 사람들이 이익이나 수입을 위해 프로그램을 개발하는 것이 아니라 자신의 자유 의지와 열정으로 프로그램을 개발합니다. 물론 이것이 프로그램의 품질에 영향을 주어서는 안 되며, 말하자면 이 사업에는 품질 실행, 안정적인 작업 및 모든 현대적인 요구 사항 충족에 대한 경쟁과 요구가 있습니다. 여기서는 수많은 램프 세트를 대체하게 된 60년대 마이크로프로세서의 출현에 주목할 가치가 있습니다. 서로 매우 다른 몇 가지 유형의 마이크로프로세서가 있습니다. 이러한 마이크로프로세서는 비트 깊이와 내장 시스템 명령이 서로 다릅니다. 가장 일반적인 것은 Intel, IBM, Celeron, AMD 등입니다. 이러한 프로세서는 모두 Intel 프로세서의 고급 아키텍처와 관련이 있습니다. 마이크로컴퓨터의 확산은 두 가지 주요 이유로 어셈블리 언어에 대한 태도를 재고하게 만들었습니다. 첫째, 어셈블리 언어로 작성된 프로그램은 훨씬 적은 메모리와 실행 시간을 필요로 합니다. 둘째, 어셈블리 언어와 그에 따른 기계 코드에 대한 지식은 기계의 아키텍처에 대한 이해를 제공하는데, 이는 고급 언어로 작업할 때 제공될 가능성이 낮습니다. 대부분의 소프트웨어 전문가는 프로그램을 작성할 때 더 쉬운 Pascal, C 또는 Delphi와 같은 고급 언어로 개발하지만 가장 강력하고 효과적인 소프트웨어전체적으로 또는 부분적으로 어셈블리 언어로 작성되었습니다. 고급 언어는 특수 문자를 피하도록 설계되었습니다. 기술적 기능들특정 컴퓨터. 그리고 어셈블리 언어는 프로세서의 특정 특성에 맞게 설계되었습니다. 따라서 특정 컴퓨터에 대한 어셈블리 언어 프로그램을 작성하려면 해당 컴퓨터의 아키텍처를 알아야 합니다. 요즘 메인 뷰는 소프트웨어 제품 EXE 파일입니다. 이것의 긍정적인 측면을 고려하면, 프로그램 작성자는 그 무결성에 대해 확신을 가질 수 있습니다. 그러나 종종 이것은 사실과 거리가 멀다. 디스어셈블러도 있습니다. 디스어셈블러를 사용하면 중단 및 프로그램 코드를 찾을 수 있습니다. 어셈블러에 능숙한 사람이 전체 프로그램을 자신의 취향에 맞게 다시 만드는 것은 어렵지 않을 것입니다. 아마도 이것이 가장 풀리지 않는 문제인 바이러스가 발생하는 곳일 것입니다. 사람들은 왜 바이러스를 작성합니까? 어떤 사람들은 놀라서 이 질문을 하고, 어떤 사람들은 분노하여 이 질문을 하지만 그럼에도 불구하고 이 작업에 해를 끼친다는 관점이 아니라 시스템 프로그래밍에 대한 관심으로 관심을 갖는 사람들이 계속 있습니다. 바이러스는 다양한 이유로 작성됩니다. 어떤 사람들은 시스템 호출을 좋아하고 다른 사람들은 어셈블러에 대한 지식을 향상시킵니다. 나는 이 모든 것을 내 글에서 설명하려고 노력할 것이다. 코스 작업. 또한 EXE 파일의 구조뿐만 아니라 어셈블리 언어에 대해서도 설명합니다.

^ 어셈블리 언어.

최초의 컴퓨터가 등장한 때부터 현재까지 어셈블리 언어에 대한 프로그래머의 생각이 어떻게 변화했는지 추적하는 것은 흥미롭습니다.

옛날에는 어셈블리가 없으면 컴퓨터가 유용한 작업을 수행할 수 없는 언어였습니다. 점차적으로 상황은 바뀌었습니다. 컴퓨터와 통신하는 더욱 편리한 수단이 등장했습니다. 하지만 다른 언어와 달리 어셈블러는 죽지 않았고, 게다가 원칙적으로는 그렇게 할 수도 없었다. 왜? 답을 찾기 위해 일반적으로 어셈블리 언어가 무엇인지 이해해 봅시다.

간단히 말해서 어셈블리 언어는 기계어를 상징적으로 표현한 것입니다. 가장 낮은 하드웨어 수준에 있는 기계의 모든 프로세스는 기계어 명령(명령어)에 의해서만 구동됩니다. 이를 통해 일반 이름에도 불구하고 각 컴퓨터 유형마다 어셈블리 언어가 다르다는 것이 분명해졌습니다. 이는 또한 적용됩니다 모습어셈블리 언어로 작성된 프로그램과 이 언어가 반영하는 아이디어.

어셈블러에 대한 지식 없이는 하드웨어와 관련된 문제(또는 프로그램 속도를 높이는 등 하드웨어에 따른 문제)를 실제로 해결하는 것은 불가능합니다.

프로그래머 또는 기타 사용자는 가상 세계를 구성하기 위한 프로그램을 비롯한 고급 도구를 사용할 수 있으며 실제로 컴퓨터가 프로그램이 작성된 언어의 명령을 실행하지 않고 변환된 표현을 실행한다는 사실을 의심하지 않을 수도 있습니다. 완전히 다른 언어, 즉 기계 언어의 지루하고 지루한 명령 시퀀스 형태입니다. 이제 그러한 사용자에게 문제가 있다고 가정해 봅시다. 비표준 문제아니면 뭔가 문제가 해결되지 않았습니다. 예를 들어, 그의 프로그램은 일부 특이한 장치와 함께 작동해야 하거나 컴퓨터 하드웨어의 작동 원리에 대한 지식이 필요한 기타 작업을 수행해야 합니다. 프로그래머가 아무리 똑똑하고 훌륭한 프로그램을 작성한 언어가 아무리 훌륭하더라도 어셈블러에 대한 지식 없이는 할 수 없습니다. 그리고 거의 모든 고급 언어 컴파일러에 모듈을 어셈블러 모듈과 연결하거나 어셈블리 수준 프로그래밍에 대한 액세스를 지원하는 수단이 포함되어 있다는 것은 우연이 아닙니다.

물론 컴퓨터 제너럴리스트의 시대는 이미 지났다. 그들이 말했듯이, 당신은 그 광대함을 받아들일 수 없습니다. 그러나 진지한 컴퓨터 교육이 구축되는 일종의 기초라는 공통점이 있습니다. 이는 이 지식을 반영하고 구현하는 컴퓨터 작동 원리, 아키텍처 및 어셈블리 언어에 대한 지식입니다.

일반적인 최신 컴퓨터(i486 또는 Pentium 기반)는 다음 구성 요소로 구성됩니다(그림 1).

쌀. 1. 컴퓨터 및 주변기기

쌀. 2. 블록 다이어그램 개인용 컴퓨터

그림(그림 1)에서 컴퓨터는 여러 개의 물리적 장치로 구성되어 있으며 각 장치는 시스템 장치라고 하는 하나의 장치에 연결되어 있음을 알 수 있습니다. 논리적으로 생각해보면 일종의 조정장치 역할을 한다는 것은 분명하다. 내부를 살펴보자 시스템 장치(모니터 안으로 들어가려고 할 필요가 없습니다. 거기에는 흥미로운 것이 없으며 게다가 위험합니다.): 케이스를 열고 보드, 블록, 연결 전선을 확인하십시오. 기능적 목적을 이해하기 위해 다음을 살펴보겠습니다. 블록 다이어그램일반적인 컴퓨터(그림 2). 이는 절대적인 정확성을 주장하지 않으며 현대 개인용 컴퓨터 요소의 목적, 상호 연결 및 일반적인 구성을 보여주기 위한 것입니다.

그림의 다이어그램에 대해 논의해 보겠습니다. 2 다소 파격적인 스타일.
사람이 새로운 것을 접할 때 미지의 것을 이해하는 데 도움이 될 수 있는 연관성을 찾는 것은 흔한 일입니다. 컴퓨터는 어떤 연관성을 불러일으키나요? 예를 들어, 나는 종종 컴퓨터를 그 사람 자신과 연관시킵니다. 왜?

사람이 컴퓨터를 만들 때 자신의 깊은 곳 어딘가에 자신과 비슷한 것을 만들고 있다고 생각했습니다. 컴퓨터에는 키보드, 마우스, 저장 장치 등 외부 세계로부터 정보를 수신하는 기관이 있습니다. 자기 디스크. 그림에서. 2 이 오르간은 시스템 버스의 오른쪽에 있습니다. 컴퓨터에는 수신된 정보를 "소화"하는 기관이 있습니다. 이는 중앙 프로세서이며 . 그리고 마지막으로 컴퓨터에는 처리 결과를 생성하는 음성 기관이 있습니다. 이것들은 오른쪽에 있는 장치 중 일부이기도 합니다.

최신 컴퓨터물론 인간과는 거리가 멀다. 그들은 상호 작용하는 생물에 비유될 수 있습니다. 외부 세계크지만 제한된 무조건 반사 세트 수준에서.
이 반사 신경 세트는 기계 명령 시스템을 형성합니다. 아무리 높은 수준의 컴퓨터와 통신을 하더라도 결국 지루하고 단조로운 기계 명령의 연속으로 귀결됩니다.
각 기계 명령은 하나 또는 다른 무조건 반사를 자극하는 일종의 자극입니다. 이 자극에 대한 반응은 항상 명확하며 마이크로 프로그램 형태의 마이크로 명령 블록에 "고정"되어 있습니다. 이 마이크로프로그램은 기계 명령을 구현하기 위한 작업을 구현하지만 컴퓨터의 특정 논리 회로에 공급되는 신호 수준에서 컴퓨터의 다양한 하위 시스템을 제어합니다. 이것이 소위 마이크로프로그램 제어의 원리이다.

사람에 대한 비유를 계속하면 다음과 같습니다. 컴퓨터가 제대로 먹기 위해서는 많은 운영 체제, 수백 가지 프로그래밍 언어에 대한 컴파일러 등이 발명되었지만 실제로는 모두 플래터에 불과합니다. 음식(프로그램)은 일정한 규칙에 따라 전달됩니다.위(컴퓨터). 컴퓨터의 위만이 다이어트, 단조로운 음식을 좋아합니다. 엄격하게 조직된 0과 1의 시퀀스 형태로 구조화된 정보를 제공하며, 이들의 조합은 기계 언어를 구성합니다.

따라서 겉으로는 다국어임에도 불구하고 컴퓨터는 단 하나의 언어, 즉 기계 명령의 언어만을 이해합니다. 물론 컴퓨터와 통신하고 작업하기 위해 이 언어를 알 필요는 없지만 조만간 거의 모든 전문 프로그래머가 이 언어를 공부해야 할 필요성에 직면하게 됩니다. 다행스럽게도 프로그래머는 다양한 조합의 의미를 이해하려고 노력할 필요가 없습니다. 이진수, 50년대부터 프로그래머들은 프로그래밍을 위해 어셈블리 언어라고 불리는 기계어의 상징적 유사체를 사용하기 시작했습니다. 이 언어는 기계어의 모든 기능을 정확하게 반영합니다. 그렇기 때문에 고급 언어와 달리 어셈블리 언어는 컴퓨터 유형마다 다릅니다.

위의 모든 것에서 우리는 어셈블리 언어가 컴퓨터의 "기본"이기 때문에 가장 효과적인 프로그램은 그 안에서만 작성할 수 있다는 결론을 내릴 수 있습니다(자격을 갖춘 프로그래머가 작성한 경우). 여기에는 작은 "하지만"이 하나 있습니다. 이는 많은 관심과 실제 경험이 필요한 매우 노동 집약적 프로세스입니다. 따라서 실제로 그들은 주로 다음을 제공해야 하는 프로그램을 어셈블러로 작성합니다. 효과적인 작업하드웨어로. 실행 시간이나 메모리 소비 측면에서 중요한 프로그램 섹션이 어셈블러로 작성되는 경우도 있습니다. 그런 다음 서브루틴 형태로 형식화되고 고급 언어의 코드와 결합됩니다.

컴퓨터의 어떤 부분이 표시되고 이 언어로 프로그래밍할 수 있는지 알아낸 후에만 컴퓨터의 어셈블리 언어를 배우기 시작하는 것이 합리적입니다. 이것은 소위 컴퓨터 프로그램 모델이며, 그 일부는 프로그래머가 사용할 수 있는 32개의 레지스터를 어느 정도 포함하는 마이크로프로세서 프로그램 모델입니다.

이러한 레지스터는 두 개의 큰 그룹으로 나눌 수 있습니다.

^ 16개의 사용자 레지스터;

16개의 시스템 레지스터.

어셈블리 언어 프로그램은 레지스터를 매우 집중적으로 사용합니다. 대부분의 레지스터에는 특정한 기능적 목적이 있습니다.

이름에서 알 수 있듯이 사용자 레지스터는 프로그래머가 프로그램을 작성할 때 사용할 수 있기 때문에 사용자 레지스터라고 합니다. 이러한 레지스터에는 다음이 포함됩니다(그림 3).

프로그래머가 데이터와 주소를 저장하는 데 사용할 수 있는 8개의 32비트 레지스터(레지스터라고도 함) 범용(론)):

6개의 세그먼트 레지스터: cs, ds, ss, es, fs, gs;

상태 및 제어 레지스터:

플래그는 플래그/플래그를 등록합니다.

명령 포인터 레지스터 eip/ip.

쌀. 3. i486 및 Pentium 마이크로프로세서의 사용자 레지스터

이러한 레지스터 중 다수가 슬래시로 표시되는 이유는 무엇입니까? 아니요, 이는 다른 레지스터가 아닙니다. 하나의 대형 32비트 레지스터의 일부입니다. 프로그램에서 별도의 개체로 사용할 수 있습니다. 이는 i8086부터 시작하여 Intel 마이크로프로세서의 최신 16비트 모델용으로 작성된 프로그램의 기능을 보장하기 위해 수행되었습니다. i486 및 Pentium 마이크로프로세서에는 대부분 32비트 레지스터가 있습니다. 세그먼트 레지스터를 제외한 그 수는 i8086의 수와 동일하지만 치수가 더 크므로 지정에 반영됩니다.
접두사 e(확장).

^ 범용 레지스터
이 그룹의 모든 레지스터를 사용하면 해당 "하위" 부분에 액세스할 수 있습니다(그림 3 참조). 이 그림을 보면 이 레지스터의 하위 16비트와 8비트 부분만 자체 주소 지정에 사용될 수 있다는 점에 유의하세요. 이들 레지스터의 상위 16비트는 독립된 객체로 사용할 수 없습니다. 이는 위에서 언급한 것처럼 최신 Intel 마이크로프로세서 16비트 모델과의 호환성을 위해 수행되었습니다.

범용 레지스터 그룹에 속하는 레지스터를 나열해 보겠습니다. 이러한 레지스터는 ALU(산술 논리 장치) 내부의 마이크로프로세서에 물리적으로 위치하므로 ALU 레지스터라고도 합니다.

eax/ax/ah/al (누산기 레지스터) - 배터리.
중간 데이터를 저장하는 데 사용됩니다. 일부 명령에서는 이 레지스터를 사용해야 합니다.

ebx/bx/bh/bl (기본 레지스터) - 기본 레지스터.
일부 객체의 기본 주소를 메모리에 저장하는 데 사용됩니다.

ecx/cx/ch/cl(카운트 레지스터) - 카운터 레지스터.
반복적인 작업을 수행하는 팀에 사용됩니다. 해당 명령의 사용은 종종 암시적이고 해당 명령의 알고리즘에 숨겨져 있습니다.
예를 들어, 루프 루프를 구성하는 명령은 특정 주소에 있는 명령으로 제어를 전달하는 것 외에도 ecx/cx 레지스터의 값을 하나씩 분석하고 감소시킵니다.

edx/dx/dh/dl (데이터 레지스터) - 데이터 레지스터.
eax/ax/ah/al 레지스터와 마찬가지로 중간 데이터를 저장합니다. 일부 명령에서는 해당 사용이 필수입니다. 일부 명령의 경우 이는 암시적으로 발생합니다.

다음 두 레지스터는 소위 체인 작업, 즉 각 요소의 체인을 순차적으로 처리하는 작업을 지원하는 데 사용되며 각 요소의 길이는 32, 16 또는 8비트일 수 있습니다.

esi/si(소스 인덱스 레지스터) - 소스 인덱스.
연결된 작업의 이 레지스터에는 소스 체인에 있는 요소의 현재 주소가 포함되어 있습니다.

edi/di (대상 인덱스 레지스터) - 수신자(수신자)의 인덱스입니다.
연결된 작업의 이 레지스터에는 대상 체인의 현재 주소가 포함됩니다.

마이크로프로세서 아키텍처에서는 스택과 같은 데이터 구조가 하드웨어 및 소프트웨어 수준에서 지원됩니다. 스택 작업을 위해 마이크로프로세서 명령 시스템에는 특수 명령이 있고 마이크로프로세서 소프트웨어 모델에는 이에 대한 특수 레지스터가 있습니다.

esp/sp (스택 포인터 레지스터) - 스택 포인터 레지스터.
현재 스택 세그먼트의 스택 맨 위에 대한 포인터를 포함합니다.

ebp/bp(기본 포인터 레지스터) - 스택 프레임 기본 포인터 레지스터입니다.
스택 내부의 데이터에 대한 무작위 액세스를 구성하도록 설계되었습니다.

스택은 임의의 데이터를 임시로 저장하는 프로그램 영역입니다. 물론 데이터를 데이터 세그먼트에 저장할 수도 있지만 이 경우 임시로 저장된 각 데이터에 대해 별도의 명명된 메모리 셀을 만들어야 하므로 프로그램 크기와 사용되는 이름 수가 늘어납니다. 스택의 편리함은 해당 영역이 재사용 가능하고 스택에 데이터를 저장하고 거기에서 검색하는 것이 이름을 지정하지 않고 효과적인 push 및 pop 명령을 사용하여 수행된다는 사실에 있습니다.
예를 들어, 스택은 전통적으로 프로그램이 서브루틴을 호출하기 전에 프로그램에서 사용하는 레지스터의 내용을 저장하는 데 사용되며, 서브루틴은 "자체 목적을 위해" 프로세서 레지스터를 사용합니다. 서브루틴이 반환된 후 레지스터의 원래 내용이 스택에서 제거됩니다. 또 다른 일반적인 기술은 스택을 통해 서브루틴에 필요한 매개변수를 전달하는 것입니다. 매개변수가 스택에 배치되는 순서를 알고 있는 서브루틴은 매개변수를 거기에서 가져와 실행 중에 사용할 수 있습니다. 구별되는 특징스택은 포함된 데이터가 검색되는 고유한 순서입니다. 언제든지 스택에서 최상위 요소만 사용할 수 있습니다. 가장 최근에 스택에 푸시된 요소입니다. 스택에서 맨 위 요소를 팝하면 다음 요소를 사용할 수 있습니다. 스택 요소는 스택에 할당된 메모리 영역에 위치하며 스택의 맨 아래(즉, 최대 주소부터)부터 순차적으로 감소하는 주소로 시작됩니다. 액세스 가능한 최상위 요소의 주소는 스택 포인터 레지스터 SP에 저장됩니다. 프로그램 메모리의 다른 영역과 마찬가지로 스택은 일부 세그먼트의 일부이거나 별도의 세그먼트를 형성해야 합니다. 두 경우 모두 이 세그먼트의 세그먼트 주소는 세그먼트 스택 레지스터 SS에 배치됩니다. 따라서 레지스터 쌍 SS:SP는 액세스 가능한 스택 셀의 주소를 설명합니다. SS는 스택의 세그먼트 주소를 저장하고 SP는 스택에 저장된 마지막 데이터의 오프셋을 저장합니다(그림 4, a). 초기 상태에서 스택 포인터 SP는 스택의 맨 아래에 있고 스택에 포함되지 않은 셀을 가리킵니다.

그림 4. 스택 구성: a - 초기 상태, b - 하나의 요소를 로드한 후(c 이 예에서는- AX 레지스터의 내용), c - 두 번째 요소를 로드한 후(DS 레지스터의 내용), d - 한 요소를 언로드한 후, d - 두 요소를 언로드하고 원래 상태로 돌아온 후.

스택에 로딩이 수행됩니다. 특별팀푸시 스택으로 작업합니다. 이 명령어는 먼저 스택 포인터의 내용을 2만큼 감소시킨 다음 피연산자를 SP의 주소에 배치합니다. 예를 들어, AX 레지스터의 내용을 스택에 임시로 저장하려면 다음 명령을 실행해야 합니다.

스택은 그림과 같은 상태가 됩니다. 1.10, 나. 스택 포인터가 2바이트 위로(낮은 주소 쪽으로) 이동하고 push 명령에 지정된 피연산자가 이 주소에 기록되는 것을 볼 수 있습니다. 다음 스택 로딩 명령은 다음과 같습니다.

스택은 그림과 같은 상태가 됩니다. 1.10, 다. 이제 스택은 두 개의 요소를 저장하며 스택 포인터 SP가 가리키는 최상위 요소에만 액세스할 수 있습니다. 일정 시간이 지난 후 스택에 저장된 레지스터의 원래 내용을 복원해야 하는 경우 팝(푸시) 명령을 실행하여 스택에서 언로드해야 합니다.

팝 DS
팝액스

스택은 얼마나 커야합니까? 프로그램에서 얼마나 집중적으로 사용되는지에 따라 다릅니다. 예를 들어 스택에 10,000바이트의 배열을 저장하려는 경우 스택은 최소한 이 크기 이상이어야 합니다. 어떤 경우에는 특히 int 21h 인터럽트 명령을 실행할 때 시스템이 스택을 자동으로 사용한다는 점을 명심해야 합니다. 이 명령을 사용하면 프로세서는 먼저 반환 주소를 스택에 푸시한 다음 DOS는 레지스터의 내용과 중단된 프로그램과 관련된 기타 정보를 스택에 푸시합니다. 따라서 프로그램이 스택을 전혀 사용하지 않더라도 스택은 여전히 ​​프로그램에 존재해야 하며 크기가 최소 수십 단어 이상이어야 합니다. 첫 번째 예에서는 스택에 128개의 단어를 할당했는데, 이는 확실히 충분합니다.

^ 어셈블러 프로그램의 구조

어셈블리 언어 프로그램은 메모리 세그먼트라고 불리는 메모리 블록의 모음입니다. 프로그램은 하나 이상의 블록 세그먼트로 구성될 수 있습니다. 각 세그먼트에는 언어 문장 모음이 포함되어 있으며 각 문장은 별도의 프로그램 코드 줄을 차지합니다.

어셈블러 명령문에는 네 가지 유형이 있습니다.

기계 명령의 상징적 유사체인 명령 또는 지침. 변환 과정에서 어셈블러 명령어는 마이크로프로세서 명령어 세트의 해당 명령으로 변환됩니다.

매크로 명령 - 특정 방식으로 형식화된 프로그램 텍스트 문장으로, 방송 중에 다른 문장으로 대체됩니다.

지시문은 어셈블러 번역기에 특정 작업을 수행하도록 지시하는 것입니다. 지시문은 기계 표현에 상응하는 항목이 없습니다.

러시아어 알파벳 문자를 포함한 모든 문자가 포함된 주석 라인입니다. 번역자는 댓글을 무시합니다.

^ 어셈블리 구문

프로그램을 구성하는 문장은 명령, 매크로, 지시문 또는 주석에 해당하는 구문 구조일 수 있습니다. 어셈블러 번역가가 이를 인식하려면 특정 구문 규칙에 따라 구성되어야 합니다. 이를 위해서는 문법 규칙과 같이 언어 구문에 대한 공식적인 설명을 사용하는 것이 가장 좋습니다. 이러한 방식으로 프로그래밍 언어를 설명하는 가장 일반적인 방법은 구문 다이어그램과 확장된 Backus-Naur 형식입니다. 을 위한 실제 사용구문 다이어그램이 더 편리합니다. 예를 들어 어셈블리 언어 문의 구문은 다음 그림에 표시된 구문 다이어그램을 사용하여 설명할 수 있습니다.

쌀. 5. 조립문 형식

쌀. 6. 지시문 형식

쌀. 7. 명령 및 매크로의 형식

이 사진들에서:

라벨 이름 - 지정하는 프로그램의 소스 코드에 있는 문장의 첫 번째 바이트 주소를 값으로 가지는 식별자입니다.

이름 - 이 지시어를 동일한 이름의 다른 지시어와 구별하는 식별자입니다. 어셈블러가 특정 지시문을 처리한 결과 해당 이름에 특정 특성이 할당될 수 있습니다.

연산 코드(OPC)와 지시문은 해당 기계 명령어, 매크로 명령어 또는 번역기 지시어에 대한 니모닉 기호입니다.

피연산자는 작업이 수행되는 개체를 지정하는 명령, 매크로 또는 어셈블러 지시문의 일부입니다. 어셈블리 언어 피연산자는 숫자 및 텍스트 상수, 레이블, 연산자 기호 및 일부 예약어를 사용하는 변수 식별자가 포함된 표현식으로 설명됩니다.

^ 구문 다이어그램을 사용하는 방법은 무엇입니까? 매우 간단합니다. 다이어그램의 입력(왼쪽)에서 출력(오른쪽)까지의 경로를 찾아 따라가기만 하면 됩니다. 그러한 경로가 존재한다면 문장이나 구성은 구문론적으로 정확합니다. 해당 경로가 없으면 컴파일러는 이 구성을 허용하지 않습니다. 구문 다이어그램 작업 시 화살표로 표시된 순회 방향에 주의하십시오. 경로 중에는 오른쪽에서 왼쪽으로 따라갈 수 있는 경로가 있을 수 있기 때문입니다. 본질적으로 구문 다이어그램은 프로그램의 입력 문장을 구문 분석할 때 번역기의 작업 논리를 반영합니다.

프로그램 텍스트를 작성할 때 허용되는 문자는 다음과 같습니다.

모든 라틴 문자: A-Z, a-z. 이 경우 대문자와 소문자는 동일한 것으로 간주됩니다.

0부터 9까지의 숫자;

기호 ?, @, $, _, &;

구분 기호, . ()< > { } + / * % ! " " ? \ = # ^.

어셈블리 언어 문장은 번역자가 이해할 수 있는 유효한 언어 기호의 구문론적으로 분리할 수 없는 시퀀스인 어휘소로 구성됩니다.

어휘는 다음과 같습니다:

식별자는 작업 코드, 변수 이름, 레이블 이름과 같은 프로그램 개체를 지정하는 데 사용되는 유효한 문자 시퀀스입니다. 식별자 작성 규칙은 다음과 같습니다. 식별자는 하나 이상의 문자로 구성될 수 있습니다. 기호로는 라틴 알파벳 문자, 숫자 및 일부 특수 문자(_, ?, $, @)를 사용할 수 있습니다. 식별자는 숫자 문자로 시작할 수 없습니다. 식별자의 길이는 최대 255자일 수 있지만 변환기는 처음 32자만 허용하고 나머지는 무시합니다. 옵션을 사용하여 가능한 식별자의 길이를 조정할 수 있습니다 명령줄 mv. 또한 번역자에게 대문자와 소문자를 구별하거나 그 차이를 무시하도록 지시할 수도 있습니다(기본적으로 수행됨).

^어셈블러 명령.

어셈블러 명령은 논리적 비교 및 ​​프로그램 구성을 위해 프로그램(사이클 및 전환)에서 제어를 전송하는 메커니즘인 요구 사항을 컴퓨터로 전송하는 기능을 보여줍니다. 그러나 프로그래밍 가능한 작업은 그다지 간단하지 않습니다. 대부분의 프로그램에는 특정 요구 사항이 달성될 때까지 여러 명령이 반복되는 일련의 루프와 여러 작업 중 어떤 작업을 수행해야 하는지 결정하는 다양한 검사가 포함되어 있습니다. 일부 명령어는 명령어 포인터의 오프셋 값을 직접 수정하여 일반적인 단계 순서를 변경하여 제어를 전달할 수 있습니다. 앞서 언급했듯이 프로세서마다 다른 명령이 있지만 80186, 80286 및 80386 프로세서에 대한 몇 가지 명령을 살펴보겠습니다.

특정 명령을 실행한 후 플래그의 상태를 설명하기 위해 eflags 플래그 레지스터의 구조를 반영하는 테이블에서 선택 항목을 사용합니다.

이 표의 맨 아래 행에는 명령이 실행된 후 플래그 값이 표시됩니다. 다음 표기법이 사용됩니다.

1 - 명령이 실행된 후 플래그가 설정됩니다(1과 동일).

0 - 명령이 실행된 후 플래그가 재설정됩니다(0과 동일).

r - 플래그 값은 명령 결과에 따라 달라집니다.

명령이 실행된 후에는 플래그가 정의되지 않습니다.

space - 명령이 실행된 후에도 플래그가 변경되지 않습니다.

다음 표기법은 구문 다이어그램에서 피연산자를 나타내는 데 사용됩니다.

r8, r16, r32 - 바이트 크기, 워드 또는 더블 워드 레지스터 중 하나의 피연산자.

m8, m16, m32, m48 - 메모리 피연산자 크기 바이트, 워드, 더블 워드 또는 48비트;

i8, i16, i32 - 즉시 피연산자 크기 바이트, 워드 또는 더블 워드;

a8, a16, a32 - 코드 세그먼트의 상대 주소(오프셋)입니다.

명령(알파벳순):

*이러한 명령에 대해 자세히 설명되어 있습니다.

추가하다
(덧셈)

덧셈

^ 명령 다이어그램:

대상, 소스 추가

목적: 바이트, 워드 또는 더블 워드 크기의 두 개의 소스 및 대상 피연산자를 추가합니다.

작업 알고리즘:

소스 및 대상 피연산자를 추가합니다.

추가 결과를 수신기에 씁니다.

플래그를 설정합니다.

명령 실행 후 플래그 상태:

애플리케이션:
add 명령은 두 개의 정수 피연산자를 추가하는 데 사용됩니다. 덧셈의 ​​결과는 첫 번째 피연산자의 주소에 배치됩니다. 추가 결과가 수신자 피연산자의 경계를 벗어나는 경우(오버플로 발생) cf 플래그와 이후에 가능한 adc 명령 사용을 분석하여 이 상황을 고려해야 합니다. 예를 들어 ax 레지스터와 ch 메모리 영역에 값을 추가해 보겠습니다. 추가할 때 오버플로 가능성을 고려하십시오.

레지스터와 레지스터 또는 메모리:

|000000dw|modregr/rm|

AX 레지스터(AL) + 즉치값:

|0000010w|--data--|w=1인 경우 데이터|

레지스터 또는 메모리 + 즉치값:

|100000sw|mod000r/m|--data--|BW=01인 경우 데이터|

부르다
(부르다)

프로시저 또는 작업 호출

^ 명령 다이어그램:

목적:

스택에 반환 지점의 주소를 저장하여 근거리 또는 원거리 프로시저로 제어를 전달하는 단계;

작업 전환.

작업 알고리즘:
피연산자 유형에 따라 결정됩니다.

Near label - eip/ip 명령 포인터의 내용이 스택으로 푸시되고 레이블에 해당하는 새 주소 값이 동일한 레지스터에 로드됩니다.

먼 레이블 - eip/ip 및 cs 명령 포인터의 내용이 스택으로 푸시됩니다. 그런 다음 먼 레이블에 해당하는 새 주소 값이 동일한 레지스터에 로드됩니다.

R16, 32 또는 m16, 32 - 제어가 전송되는 현재 명령 세그먼트의 오프셋을 포함하는 레지스터 또는 메모리 셀을 정의합니다. 제어가 전송되면 eip/ip 명령 포인터의 내용이 스택으로 푸시됩니다.

메모리 포인터 - 호출된 프로시저에 대한 4바이트 또는 6바이트 포인터를 포함하는 메모리 위치를 정의합니다. 이러한 포인터의 구조는 2+2 또는 2+4바이트입니다. 이러한 포인터의 해석은 마이크로프로세서의 작동 모드에 따라 다릅니다.

^ 명령 실행 후 플래그 상태(작업 전환 제외):

명령을 실행해도 플래그에는 영향을 미치지 않습니다.

태스크가 전환되면 전환되는 태스크의 TSS 상태 세그먼트에 있는 eflags 레지스터에 대한 정보에 따라 플래그 값이 변경됩니다.
애플리케이션:
호출 명령을 사용하면 반환 지점의 주소를 유지하면서 서브루틴으로의 유연하고 다양한 제어 전송을 구성할 수 있습니다.

개체 코드(4가지 형식):

세그먼트 내 직접 주소 지정:

|11101000|disp-low|diep-high|

세그먼트의 간접 주소 지정:

|11111111|mod010r/m|

세그먼트 간 간접 주소 지정:

|11111111|mod011r/m|

세그먼트 간 직접 주소 지정:

|10011010|오프셋-낮음|오프셋-높음|세그-낮음|세그-높음|

CMP
(CoMPare 피연산자)

피연산자 비교

^ 명령 다이어그램:

cmp 피연산자1,연산자2

목적: 두 피연산자를 비교합니다.

작업 알고리즘:

빼기 수행(연산자1-연산자2);

결과에 따라 플래그를 설정하고 Operand1 및 Operand2를 변경하지 마십시오(즉, 결과를 기억하지 마십시오).

애플리케이션:
이 명령피연산자를 변경하지 않고 빼기로 두 피연산자를 비교하는 데 사용됩니다. 명령 결과에 따라 플래그가 설정됩니다. cmp 명령은 조건부 점프 명령 및 값별 바이트 설정 명령 setcc와 함께 사용됩니다.

개체 코드(세 가지 형식):

레지스터 또는 레지스터가 있는 메모리:

|001110dw|modregr/m|

AX(AL) 레지스터의 즉시값:

|0011110w|--data--|w=1인 경우 데이터|

레지스터 또는 메모리가 있는 즉시 값:

|100000sw|mod111r/m|--data--|sw=0인 경우 데이터|

12월
(피연산자를 1씩 감소)

피연산자를 하나씩 감소

^ 명령 다이어그램:

12월 피연산자

목적: 메모리나 레지스터의 피연산자 값을 1만큼 감소시킵니다.

작업 알고리즘:
이 명령은 피연산자에서 1을 뺍니다. 명령 실행 후 플래그 상태:

애플리케이션:
dec 명령어는 메모리나 레지스터의 바이트, 워드, 더블 워드의 값을 1씩 감소시키는 데 사용됩니다. 그러나 이 명령은 cf 플래그에 영향을 주지 않습니다.

등록: |01001reg|

^ 레지스터 또는 메모리: |1111111w|mod001r/m|

DIV
(부호 없는 DIVide)

부호 없는 나눗셈

팀 개요:

사업부 분배기

목적: 두 개의 부호 없는 이진 값 사이의 나누기 연산을 수행합니다.

^ 운영 알고리즘:
이 명령에는 두 개의 피연산자(피제수와 제수)가 필요합니다. 피제수는 암시적으로 지정되며 해당 크기는 명령에 지정된 제수의 크기에 따라 달라집니다.

제수가 바이트 크기이면 피제수는 ax 레지스터에 있어야 합니다. 연산 후 몫은 al에 배치되고 나머지는 ah에 배치됩니다.

제수가 단어 크기인 경우 피제수는 레지스터 쌍 dx:ax에 있어야 하며 피제수의 하위 부분은 ax에 있어야 합니다. 연산 후 몫은 ax에 배치되고 나머지는 dx에 배치됩니다.

제수가 더블 워드인 경우 피제수는 레지스터 쌍 edx:eax에 위치해야 하며 피제수의 하위 부분은 eax에 위치해야 합니다. 연산 후 몫은 eax에 나머지는 edx에 저장됩니다.

^ 명령 실행 후 플래그 상태:

애플리케이션:
이 명령은 피연산자의 정수 나누기를 수행하여 나눗셈의 몫과 나머지로 나눗셈 결과를 생성합니다. 나누기 작업을 수행할 때 예외가 발생할 수 있습니다: 0 - 나누기 오류. 이 상황은 두 가지 경우 중 하나에서 발생합니다. 제수가 0이거나 몫이 너무 커서 eax/ax/al 레지스터에 맞지 않습니다.

개체 코드:

|1111011w|mod110r/m|

정수
(방해하다)

인터럽트 서비스 루틴 호출

^ 명령 다이어그램:

정수 인터럽트_번호

목적: 명령 피연산자에 의해 지정된 인터럽트 번호로 인터럽트 서비스 루틴을 호출합니다.

^ 운영 알고리즘:

플래그 레지스터 eflags/flags 및 반환 주소를 스택에 푸시합니다. 반환 주소를 쓸 때 세그먼트 레지스터 cs의 내용이 먼저 쓰여진 다음 명령 포인터 eip/ip의 내용이 쓰여집니다.

if 및 tf 플래그를 0으로 재설정합니다.

인터럽트 서비스 프로그램으로 제어권을 넘겨준다. 지정된 번호. 제어 전송 메커니즘은 마이크로프로세서의 작동 모드에 따라 다릅니다.

^ 명령 실행 후 플래그 상태:

애플리케이션:
구문에서 볼 수 있듯이 이 명령에는 두 가지 형식이 있습니다.

int 3 - 고유한 개별 연산 코드 0cch를 가지며 1바이트를 차지합니다. 이러한 상황에서는 명령의 첫 번째 바이트를 대체하여 중단점을 설정하기 위해 다양한 소프트웨어 디버거에서 사용하는 것이 매우 편리합니다. 명령 시퀀스에서 작동 코드 0cch의 명령을 만난 마이크로프로세서는 소프트웨어 디버거와 통신하는 데 사용되는 벡터 번호 3의 인터럽트 처리 프로그램을 호출합니다.

명령의 두 번째 형식은 2바이트를 차지하고 0cdh의 opcode를 가지며 0~255 범위의 벡터 번호를 사용하여 인터럽트 서비스 루틴에 대한 호출을 시작할 수 있습니다. 언급한 바와 같이 제어 전송의 특징은 마이크로프로세서의 작동 모드에 따라 달라집니다.

개체 코드(두 가지 형식):

등록: |01000reg|

^ 레지스터 또는 메모리: |1111111w|mod000r/m|

J.C.C.
JCXZ/JECXZ
(조건이 있는 경우 점프)

(CX=0인 경우 점프/ECX=0인 경우 점프)

조건이 충족되면 점프

CX/ECX가 0이면 점프

^ 명령 다이어그램:

JCC 라벨
jcxz 라벨
jecxz 라벨

목적: 일부 조건에 따라 현재 명령 세그먼트 내에서 전환합니다.

^ 명령 알고리즘(jcxz/jecxz 제외):
opcode에 따라 플래그 상태 확인(확인 중인 조건을 반영함):

테스트 중인 조건이 참이면 피연산자가 지정한 셀로 이동합니다.

확인 중인 조건이 거짓이면 다음 명령으로 제어를 전달합니다.

jcxz/jecxz 명령의 알고리즘:
ecx/cx 레지스터의 내용이 0과 같은 조건을 확인합니다.

상태를 확인하는 경우

기계 명령 수준의 프로그래밍은 프로그램을 작성할 수 있는 최소 수준입니다. 기계 명령 시스템은 컴퓨터 하드웨어에 명령을 내려 필요한 작업을 구현하기에 충분해야 합니다.

각 기계 명령은 두 부분으로 구성됩니다.

  • 운영 - "무엇을 해야할지"를 결정합니다.
  • 피연산자 - 처리 개체 정의, "무엇을 해야할지".

어셈블리 언어로 작성된 마이크로프로세서 기계 명령은 다음 구문 형식을 갖는 한 줄입니다.

명령/지시어 레이블 피연산자 ;주석

이 경우 해당 줄의 필수 필드는 명령 또는 지시문입니다.

레이블, 명령/지시문 및 피연산자(있는 경우)는 하나 이상의 공백이나 탭 문자로 구분됩니다.

명령이나 지시문이 다음 줄에서 계속되어야 하는 경우 백슬래시 문자(\)가 사용됩니다.

기본적으로 어셈블리 언어는 명령이나 지시문을 작성할 때 대문자와 소문자를 구분하지 않습니다.

코드 예시:

카운트 DB 1 ;이름, 지시문, 피연산자 1개
이동 eax,0 ;명령, 두 개의 피연산자
cbw ; 팀

태그

상표 어셈블리 언어에는 다음 기호가 포함될 수 있습니다.

  • 라틴 알파벳의 모든 문자;
  • 0부터 9까지의 숫자;
  • 특수 문자: _, @, $, ?.

마침표는 레이블의 첫 번째 문자로 사용할 수 있지만 일부 컴파일러에서는 이 문자 사용을 권장하지 않습니다. 예약된 어셈블러 이름(지시문, 연산자, 명령 이름)은 레이블로 사용할 수 없습니다.

레이블의 첫 번째 문자는 문자 또는 특수 문자여야 합니다(숫자는 제외). 최대 길이태그 – 31자. 어셈블러 지시문이 포함되지 않은 줄에 작성된 모든 레이블은 콜론(:)으로 끝나야 합니다.

마이크로프로세서가 수행해야 하는 작업을 번역자에게 알려줍니다. 데이터 세그먼트에서 명령(또는 지시문)은 필드, 작업 공간 또는 상수를 정의합니다. 코드 세그먼트에서 명령은 이동(mov) 또는 추가(add)와 같은 작업을 지정합니다.

지시어

어셈블러에는 어셈블리 및 나열 프로세스를 제어할 수 있는 여러 연산자가 있습니다. 이러한 연산자를 호출합니다. 지시문 . 이는 프로그램을 조립하는 과정에서만 작동하며 명령과 달리 기계어를 생성하지 않습니다.

피연산자

피연산자 – 기계 명령이나 프로그래밍 언어 명령문이 실행되는 개체입니다.
명령어에는 하나 또는 두 개의 피연산자가 있을 수도 있고 피연산자가 전혀 없을 수도 있습니다. 피연산자 수는 명령어 코드에 의해 암시적으로 지정됩니다.
예:

  • 피연산자 없음 ret ;Return
  • 피연산자 1개 증가 ecx ;ecx 증가
  • 두 피연산자는 eax,12를 더하고, eax에 12를 더합니다.

레이블, 명령(지시문) 및 피연산자는 줄의 특정 위치에서 시작할 필요가 없습니다. 그러나 프로그램을 더 쉽게 읽을 수 있도록 열에 작성하는 것이 좋습니다.

피연산자는 다음과 같습니다.

  • 식별자;
  • 작은따옴표나 큰따옴표로 묶인 문자열;
  • 2진수, 8진수, 10진수 또는 16진수 체계의 정수입니다.
식별자

식별자 – 연산 코드, 변수 이름, 라벨 이름과 같은 프로그램 개체를 나타내는 데 사용되는 유효한 문자 시퀀스.

식별자 기록 규칙.

  • 식별자는 하나 이상의 문자로 구성될 수 있습니다.
  • 기호로는 라틴 알파벳 문자, 숫자 및 일부 특수 문자(_, ?, $, @)를 사용할 수 있습니다.
  • 식별자는 숫자 문자로 시작할 수 없습니다.
  • 식별자의 길이는 최대 255자까지 가능합니다.
  • 변환기는 식별자의 처음 32자를 허용하고 나머지는 무시합니다.
코멘트

주석은 실행 가능한 줄과 문자로 구분됩니다. . 이 경우 세미콜론 이후부터 줄 끝까지 작성된 모든 내용은 주석입니다. 프로그램에서 주석을 사용하면 특히 명령 세트의 목적이 불분명한 경우 프로그램의 명확성이 향상됩니다. 주석에는 공백을 포함하여 인쇄 가능한 모든 문자가 포함될 수 있습니다. 주석은 전체 줄에 걸쳐 있을 수도 있고 같은 줄의 명령 뒤에 올 수도 있습니다.

어셈블리 프로그램 구조

어셈블리 언어로 작성된 프로그램은 다음과 같은 여러 부분으로 구성될 수 있습니다. 모듈 . 각 모듈에는 하나 이상의 데이터, 스택 및 코드 세그먼트가 정의되어 있습니다. 완전한 어셈블러 프로그램에는 실행이 시작되는 하나의 기본 모듈이 포함되어야 합니다. 모듈에는 적절한 지시문을 사용하여 선언된 코드 세그먼트, 데이터 세그먼트 및 스택 세그먼트가 포함될 수 있습니다. 세그먼트를 선언하기 전에 .MODEL 지시문을 사용하여 메모리 모델을 지정해야 합니다.

어셈블리 언어로 된 "아무 것도 하지 않는" 프로그램의 예:

686P
.모델 플랫, STDCALL
.데이터
.암호
시작:

RET
종료 시작

이 프로그램에는 하나의 마이크로프로세서 명령만 포함되어 있습니다. 이 명령은 RET입니다. 프로그램이 올바르게 종료되는지 확인합니다. 일반적으로 이 명령은 프로시저를 종료하는 데 사용됩니다.
프로그램의 나머지 부분은 번역기 작동에 관한 것입니다.
.686P - Pentium 6(Pentium II) 보호 모드 명령이 허용됩니다. 이 지시어는 프로세서 모델을 나타내는 지원되는 어셈블러 명령어 세트를 선택합니다. 지시문 끝에 표시된 문자 P는 프로세서가 보호 모드에서 작동 중임을 번역자에게 알립니다.
.MODEL FLAT, stdcall - 플랫 메모리 모델. 이 메모리 모델은 수술실에서 사용됩니다. 윈도우 시스템. 표준 호출
.DATA는 데이터가 포함된 프로그램 세그먼트입니다.
.CODE는 코드가 포함된 프로그램 블록입니다.
시작 - 라벨. 어셈블러에서 태그는 현대 고급 언어에서는 말할 수 없는 큰 역할을 합니다.
END START - 프로그램의 끝과 프로그램 실행이 START 라벨로 시작되어야 한다는 번역자에게 보내는 메시지입니다.
각 모듈에는 끝을 표시하는 END 지시문이 포함되어야 합니다. 소스 코드프로그램들. END 지시어 뒤에 오는 모든 줄은 무시됩니다. END 지시어를 생략하면 오류가 발생합니다.
END 지시문 뒤에 지정된 레이블은 프로그램 실행이 시작되는 기본 모듈의 이름을 변환기에게 알려줍니다. 프로그램에 하나의 모듈이 포함되어 있으면 END 지시문 뒤의 레이블을 생략할 수 있습니다.

어셈블리어 명령어(강의)

강의 계획

1. 주요 운영 그룹.

펜티엄.

1. 주요 업무그룹

마이크로프로세서는 다음과 같은 주요 작업 그룹을 구현하는 일련의 명령을 실행합니다.

전달 작업

산술 연산,

논리 연산

교대근무

비교 및 테스트 작업

비트 연산

프로그램 관리 운영

프로세서 제어 작업.

2. 프로세서 명령의 니모닉 코드 펜티엄

명령을 설명할 때 일반적으로 해당 니모닉 지정(니모닉 코드)이 사용되며, 이는 어셈블리 언어로 프로그래밍할 때 명령을 지정하는 데 사용됩니다. 을 위한 다른 버전일부 명령의 어셈블러 니모닉 코드는 다를 수 있습니다. 예를 들어, 서브루틴을 호출하는 명령의 경우 니모닉 코드가 사용됩니다.부르다 또는 JSR (“다음으로 점프하세요. 서브루틴"). 그러나 주요 유형의 마이크로프로세서에 대한 대부분의 명령에 대한 니모닉 코드는 수행되는 작업을 정의하는 해당 영어 단어의 약어이기 때문에 동일하거나 약간 다릅니다. 프로세서에 채택된 명령 니모닉 코드를 살펴보겠습니다.펜티엄.

명령을 전달합니다. 이 그룹의 주요 팀은 팀입니다.MOV , 두 레지스터 간 또는 레지스터와 메모리 셀 간 데이터 전송을 제공합니다. 일부 마이크로프로세서는 메모리에서 여러 레지스터 내용의 대량 전송뿐만 아니라 두 메모리 셀 간의 전송을 구현합니다. 예를 들어, 68 제품군의 마이크로프로세서모토로라 xxx 명령을 실행하다이동하다 , 한 메모리 셀에서 다른 메모리 셀로의 전송을 제공하고 명령무브엠 , 지정된 레지스터 세트(최대 16개 레지스터)의 내용을 메모리에 쓰거나 메모리에서 로드합니다. 팀XCHG 두 개의 프로세서 레지스터 또는 레지스터와 메모리 셀의 내용을 상호 교환합니다.

입력 명령 안에 그리고 출력 밖으로 프로세서 레지스터에서 외부 장치로 데이터를 전송하거나 외부 장치에서 레지스터로 데이터를 수신하는 것을 구현합니다. 데이터가 전송되는 인터페이스 장치(입/출력 포트)의 번호를 지정하는 명령입니다. 많은 마이크로프로세서에는 액세스에 대한 특별한 지침이 없습니다. 외부 장치. 이 경우 시스템 내 데이터의 입출력은 다음과 같은 명령어를 이용하여 수행된다.MOV , 필요한 인터페이스 장치의 주소를 지정합니다. 따라서 외부 장치는 메모리 셀로 어드레싱되며, 시스템에 연결된 인터페이스 장치(포트)의 주소가 위치하는 주소 공간에는 특정 섹션이 할당된다.

산술 연산 명령. 이 그룹의 주요 명령은 덧셈, 뺄셈, 곱셈, 나눗셈이며 다양한 옵션이 있습니다. 추가 명령 추가하다 그리고 빼기 보결 해당 작업을 수행하십시오.두 개의 레지스터, 즉 레지스터와 메모리 위치에 의해 소유되거나 직접 피연산자를 사용하여 소유됩니다. 팀 기원 후 , S.B. 속성 값을 고려하여 덧셈과 뺄셈을 수행합니다., 이전 작업 수행 중 전송을 구성할 때 설정합니다. 이러한 명령을 사용하면 비트 수가 프로세서 용량을 초과하는 피연산자의 순차적 추가가 구현됩니다. 팀 N.E.G. 피연산자의 부호를 변경하여 2의 보수로 변환합니다.

곱셈과 나눗셈 연산은 부호 있는 숫자(명령어)에 대해 수행될 수 있습니다. 멀, DIV ) 또는 서명되지 않은 (명령 MUL, DIV ). 피연산자 중 하나는 항상 레지스터에 있고, 두 번째 피연산자는 레지스터, 메모리 셀에 있거나 직접 피연산자일 수 있습니다. 작업 결과는 레지스터에 있습니다. 곱할 때 (명령 , 이물 ) 결과는 두 개의 레지스터가 사용되는 더블 비트입니다. 나눌 때 (명령DIV , IDIV ) 피제수로 이중 비트 피연산자가 사용되어 두 개의 레지스터에 배치되고 결과적으로 몫과 나머지가 두 개의 레지스터에 기록됩니다.

논리 연산 명령 . 거의 모든 마이크로프로세서는 명령을 사용하여 동일한 피연산자 비트에 대해 수행되는 논리 연산 AND, OR, Exclusive OR을 수행합니다. 그리고, 또는, 엑스 또는 . 연산은 두 레지스터, 즉 레지스터와 메모리 위치의 내용에 대해 수행되거나 직접 피연산자를 사용하여 수행됩니다. 팀 아니다 피연산자의 각 비트 값을 반전시킵니다.

시프트 명령. 마이크로프로세서는 주소가 지정된 피연산자의 산술, 논리 및 순환 시프트를 하나 이상의 비트로 수행합니다. 이동될 피연산자는 레지스터나 메모리 위치에 있을 수 있으며, 이동 비트 수는 명령어에 포함된 직접 피연산자에 의해 지정되거나 지정된 레지스터의 내용에 의해 결정됩니다. 환승 표시는 일반적으로 교대 구현에 포함됩니다.상태 레지스터(S.R.또는 이플래그)에는 레지스터나 메모리 셀에서 제거된 피연산자의 마지막 비트가 포함되어 있습니다.

비교 및 테스트 명령 . 피연산자 비교는 일반적으로 다음 명령을 사용하여 수행됩니다.CMP , 피연산자를 빼고 특성 값을 설정합니다. N, Z, V, C얻은 결과에 따라 상태 레지스터에 기록됩니다. 이 경우 뺄셈 결과는 저장되지 않으며 피연산자의 값도 변경되지 않습니다. 획득된 특징값에 대한 후속 분석을 통해 상대값(>,<, =) операндов со знаком или без знака. Использование различных способов адресации позволяет производит сравнение содержимого двух регистров, регистра и ячейки памяти, непосредственно заданного операнда с содержимым регистра или ячейки памяти.

일부 마이크로프로세서는 테스트 명령을 실행합니다. TST , 이는 비교 명령어의 단일 피연산자 버전입니다. 이 명령이 실행되면 부호가 설정됩니다. 엔,지주소가 지정된 피연산자의 부호와 값(0이 아니거나 같음)에 따라 결정됩니다.

비트 연산 지침 . 이 명령은 속성의 값을 설정합니다.테스트 중인 비트 값에 따라 상태 레지스터에 주소가 지정된 피연산자에서. 일부 마이크로프로세서에서는 비트 테스트 결과에 따라 속성이 설정됩니다.. 테스트 비트 수N명령에 지정된 레지스터의 내용이나 직접 피연산자에 의해 지정됩니다.

이 그룹의 명령은 테스트 중인 비트를 변경하기 위한 다양한 옵션을 구현합니다. 비티 이 비트의 값을 변경하지 않고 유지합니다.명령 에스 사후 테스트에서 값을 설정합니다. =1 및 명령 - 의미 =0.팀 테스트 후 비트 bn의 값을 반전시킵니다.

프로그램 관리 운영. 프로그램을 제어하기 위해 다음과 같은 많은 명령이 사용됩니다.

- 무조건적인 제어 전송 명령;

- 조건부 점프 명령;

- 프로그램 주기를 구성하는 팀;

- 인터럽트 명령;

- 속성을 변경하는 명령입니다.

무조건적인 제어권 이전은 명령에 의해 수행됩니다.JMP , 프로그램 카운터에 로드됩니다.PC실행할 다음 명령의 주소인 새 콘텐츠입니다. 이 주소는 명령에 직접 지정되거나JMP (직접 주소 지정) 또는 현재 내용의 합으로 계산됩니다.PC부호 있는 숫자(상대 주소 지정)인 명령에 지정된 오프셋입니다. 왜냐하면PC다음 프로그램 명령의 주소를 포함하며, 후자의 방법은 점프 주소, 지정된 바이트 수만큼 다음 주소에 대한 오프셋을 지정합니다. 양수 오프셋을 사용하면 프로그램의 후속 명령으로 전환되고 음수 오프셋을 사용하면 이전 명령으로 전환됩니다.

서브루틴은 명령을 사용하여 무조건적으로 제어를 전송함으로써 호출되기도 합니다.부르다 (또는 JSR ). 그러나 이 경우에는 로드하기 전에PC 서브루틴의 첫 번째 명령 주소를 지정하는 새 내용이 있는 경우, 서브루틴 실행 후 메인 프로그램(또는 이전 명령)으로 복귀하려면 현재 값(다음 명령의 주소)을 저장해야 합니다. 서브루틴을 중첩할 때 서브루틴). 조건부 점프 명령(프로그램 분기)이 로드됩니다.PC일반적으로 상태 레지스터의 다양한 속성의 현재 값에 따라 설정되는 특정 조건이 충족되면 새로운 콘텐츠가 생성됩니다. 조건이 충족되지 않으면 다음 프로그램 명령이 실행됩니다.

기능 제어 명령은 기능이 저장된 상태 레지스터의 내용을 읽고 개별 기능의 값을 변경하는 쓰기 기능을 제공합니다. 예를 들어 펜티엄 프로세서는 다음 명령을 구현합니다. LAHF 그리고 SAHF , 상태 레지스터에서 부호가 포함된 하위 바이트를 로드합니다. EFLAG레지스터의 하위 바이트로 EAX그리고 낮은 바이트를 패딩 이플래그등록부에서 EA엑스.. 팀 CLC, STC전송 기호 CF=0, CF=1의 값 설정을 수행하고 명령을 수행합니다. CMC이 속성의 값이 반전됩니다.속성은 조건부 전환 중 프로그램 실행 흐름을 결정하므로 속성 변경 명령은 일반적으로 프로그램을 제어하는 ​​데 사용됩니다.

프로세서 제어 명령 . 이 그룹에는 중지 명령, 작동 안 함 명령 및 프로세서나 개별 블록의 작동 모드를 결정하는 여러 명령이 포함됩니다. 팀HLT 프로그램 실행을 중지하고 프로세서를 중지 상태로 전환합니다. 이 상태는 인터럽트 또는 재시작 신호가 수신되면 종료됩니다(초기화 ). 팀 안돼 (“empty” 명령)은 어떠한 작업도 수행하지 않는 명령으로, 프로그램 지연을 구현하거나 프로그램에 형성된 공백을 메우기 위해 사용됩니다.

특수팀 CLI, STI 인터럽트 요청 서비스를 금지하고 활성화합니다. 프로세서에서펜티엄 이를 위해 제어 비트(플래그)가 사용됩니다.만약에기록부에 이플래그.

많은 최신 마이크로프로세서는 사용자나 다른 장치가 특정 시스템에서 사용되는 프로세서 유형에 대한 정보를 얻을 수 있도록 식별 명령을 발행합니다. 프로세서에서 펜투임이에 대한 명령은 CPUID , 프로세서에 대한 필요한 데이터가 레지스터에 입력되는 동안 EAXEBXECXEDX그런 다음 사용자나 운영 체제에서 읽을 수 있습니다.

프로세서가 구현하는 작동 모드와 처리 중인 특정 유형의 데이터에 따라 실행되는 명령 세트가 크게 확장될 수 있습니다.

일부 프로세서는 이진수로 산술 연산을 수행하거나 이러한 숫자를 처리할 때 결과를 수정하기 위해 특수 명령을 실행합니다. 많은 고성능 프로세서에는 다음이 포함됩니다. FPU - 숫자 처리 장치"부동 소수점".

많은 최신 프로세서는 여러 정수 또는 숫자의 그룹 처리를 구현합니다.씨 원리에 따라 하나의 명령을 사용하는 "부동 소수점" SIMD(“단일 명령어 – 다중 데이터” ”) - “하나의 명령 – 많은 양의 데이터.” 여러 피연산자에 대한 연산을 동시에 실행하면 비디오 및 오디오 데이터 작업 시 프로세서 성능이 크게 향상됩니다. 이러한 작업은 이미지, 오디오 신호 및 기타 응용 프로그램을 처리하는 데 널리 사용됩니다. 이러한 작업을 수행하기 위해 다양한 유형의 프로세서에서 해당 명령 세트를 구현하는 프로세서에 특수 블록이 도입되었습니다.펜티엄, 애슬론) 이름을 얻었습니다MMX (“ 밀티- 미디어 확장 ”) – 멀티미디어 확장,SSE(“스트리밍 SIMD 확장”) – 스트리밍 SIMD - 확대, “3 확대– 3차원 확장.

회사 프로세서의 특징인텔 , 80286 모델부터 프로세서가 보호된 가상 주소 모드로 작동할 때 제공되는 메모리 액세스 우선 제어입니다.보호 모드 "(보호 모드). 이 모드를 구현하려면 채택된 우선 순위 액세스 알고리즘에 따라 메모리 보호를 구성하는 데 사용되는 특수 명령 그룹이 사용됩니다.

1. PC 아키텍처..........................................................................................................5

    1.1. 레지스터.

    1.1.1 범용 레지스터.

1.1.2. 세그먼트 레지스터

1.1.3 플래그 레지스터

1.2. 기억의 조직.

1.3. 데이터 프레젠테이션.

1.3.1 데이터 유형

1.3.2 문자와 문자열의 표현

2. 어셈블러의 프로그램 명령문 .............................................

    1. 어셈블리 언어 명령

2.2. 주소 지정 모드 및 기계 명령어 형식

3. 의사 연산자 ..............................................................

3.1 데이터 정의 지시어

3.2 어셈블러 프로그램의 구조

3.2.1 프로그램 세그먼트. 지시를 취하다

3.2.3 단순화된 분할 지시어

4. 프로그램 조립 및 구성 ..............

5. 데이터 전송 명령..........................................................

    5.1 일반 명령

    5.2 스택 명령

5.3 I/O 명령

5.4 주소 전달 명령

5.5 플래그 전달 명령

6. 산술 명령어 ..............................................................

    6.1 이진 정수에 대한 산술 연산

6.1.1 덧셈과 뺄셈

6.1.2 수신자를 1씩 증가, 감소시키는 명령

6.2 곱셈과 나눗셈

6.3 표시 변경

7. 논리연산 ..........................................................

8. 교대 및 순환 교대..................................................................................

9. 문자열 연산..........................................................................

10. 프로그램의 논리와 구성..........................................

10.1 무조건 점프

10.2 조건부 점프

10.4 어셈블리 언어의 절차

10.5 INT 인터럽트

10.6 시스템 소프트웨어

10.6.1.1 키보드 읽기.

10.6.1.2 화면에 문자 표시하기

10.6.1.3 프로그램 종료.

10.6.2.1 디스플레이 모드 선택

11. 디스크 메모리..........................................................................

11.2 파일 배포 테이블

11.3 디스크 I/O 작업

11.3.1 디스크에 파일 쓰기

11.3.1.1 ASCIIZ 데이터

11.3.1.2 파일번호

11.3.1.3 디스크 파일 생성

11.3.2 디스크 파일 읽기

소개

어셈블리어는 기계어를 상징적으로 표현한 것입니다. 가장 낮은 하드웨어 수준의 개인용 컴퓨터(PC)의 모든 프로세스는 기계어 명령(명령어)에 의해서만 구동됩니다. 어셈블러에 대한 지식 없이는 하드웨어와 관련된 문제(또는 프로그램 속도를 높이는 등 하드웨어에 따른 문제)를 실제로 해결하는 것은 불가능합니다.

어셈블러는 PC 구성 요소에 대한 직접 명령의 편리한 형태이며 이러한 구성 요소를 포함하는 집적 회로, 즉 PC 마이크로프로세서의 속성과 기능에 대한 지식이 필요합니다. 따라서 어셈블리 언어는 PC의 내부 구성과 직접적인 관련이 있습니다. 그리고 거의 모든 고급 언어 컴파일러가 프로그래밍의 어셈블리 수준에 대한 액세스를 지원하는 것은 우연이 아닙니다.

전문 프로그래머 교육의 한 요소는 반드시 어셈블러에 대한 연구입니다. 어셈블리 언어 프로그래밍에는 PC 아키텍처에 대한 지식이 필요하기 때문에 다른 언어로 보다 효율적인 프로그램을 만들고 이를 어셈블리 언어 프로그램과 결합할 수 있기 때문입니다.

이 매뉴얼에서는 Intel 마이크로프로세서 기반 컴퓨터의 어셈블리 언어 프로그래밍에 대해 설명합니다.

이 튜토리얼은 프로세서 아키텍처와 어셈블리 언어 프로그래밍의 기본 사항, 주로 소프트웨어 제품 개발자에 관심이 있는 모든 사람을 대상으로 합니다.

    PC 아키텍처.

컴퓨터 아키텍처는 컴퓨터의 구조적, 회로적, 논리적 구성을 반영하는 추상적인 표현입니다.

모든 최신 컴퓨터에는 공통적이고 개별적인 아키텍처 속성이 있습니다. 개별 속성은 특정 컴퓨터 모델마다 고유합니다.

컴퓨터 아키텍처의 개념은 다음과 같습니다.

    컴퓨터 블록 다이어그램;

    컴퓨터 블록 다이어그램의 요소에 액세스하는 수단 및 방법;

    레지스터의 설정 및 가용성;

    조직 및 주소 지정 방법;

    컴퓨터 데이터의 표현 방법 및 형식;

    컴퓨터 기계 명령어 세트;

    기계 명령어 형식;

    인터럽트 처리.

컴퓨터 하드웨어의 주요 요소: 시스템 장치, 키보드, 디스플레이 장치, 디스크 드라이브, 인쇄 장치(프린터) 및 다양한 통신 장비. 시스템 장치는 마더보드, 전원 공급 장치 및 추가 카드용 확장 셀로 구성됩니다. 마더보드에는 마이크로프로세서, ROM(읽기 전용 메모리), RAM(Random Access Memory) 및 보조 프로세서가 포함되어 있습니다.

      레지스터.

마이크로프로세서 내부의 정보는 어느 정도 프로그래머가 사용할 수 있는 32개의 레지스터(사용자 16개, 시스템 16개) 그룹에 포함되어 있습니다. 매뉴얼은 8088-i486 마이크로프로세서 프로그래밍에 전념하고 있으므로 사용자가 액세스할 수 있는 마이크로프로세서의 내부 레지스터에 대한 논의로 이 주제를 시작하는 것이 가장 논리적입니다.

사용자 레지스터는 프로그래머가 프로그램을 작성하는 데 사용됩니다. 이러한 레지스터에는 다음이 포함됩니다.

    8개의 32비트 레지스터(범용 레지스터) EAX/AX/AH/AL, EBX/BX/BH/BL, ECX/CX/CH/CL, EDX/DX/DLH/DL, EBP/BP, ESI/SI, EDI/DI, ESP/SP;

    6개의 16비트 세그먼트 레지스터: CS, DS, SS, ES, FS, GS;

    상태 및 제어 레지스터: EFLAGS/FLAGS 플래그 레지스터 및 EIP/IP 명령 포인터 레지스터.

하나의 32비트 레지스터의 일부는 슬래시로 표시됩니다. 접두어 E(확장)는 32비트 레지스터의 사용을 나타냅니다. 바이트 작업을 위해 접두어 L(낮음) 및 H(높음)가 있는 레지스터가 사용됩니다(예: AL, CH - 레지스터의 16비트 부분의 낮은 바이트와 높은 바이트를 나타냄).

        범용 레지스터.

EAX/AX/AH/AL(누산기 레지스터) – 배터리. 곱셈과 나눗셈, I/O 연산, 일부 문자열 연산에 사용됩니다.

EBX/BX/BH/BL – 기본 레지스터(기본 레지스터), 메모리에서 데이터 주소를 지정할 때 자주 사용됩니다.

ECX/CX/CH/CL – 카운터(카운트 레지스터), 루프 반복 횟수에 대한 카운터로 사용됩니다.

EDX/DX/DH/DL – 데이터 레지스터(데이터 레지스터), 중간 데이터를 저장하는 데 사용됩니다. 일부 팀에서는 해당 사용이 필수입니다.

이 그룹의 모든 레지스터는 "하위" 부분에 대한 액세스를 허용합니다. 이러한 레지스터의 하위 16비트 및 8비트 부분만 자체 주소 지정에 사용될 수 있습니다. 이들 레지스터의 상위 16비트는 독립된 객체로 사용할 수 없습니다.

길이가 32, 16 또는 8비트인 요소 체인의 순차적 처리를 허용하는 문자열 처리 명령을 지원하려면 다음이 사용됩니다.

ESI/SI(소스 인덱스 레지스터) – 색인 원천. 현재 소스 요소의 주소를 포함합니다.

EDI/DI(대상 인덱스 레지스터) – 색인 수화기(받는 사람). 대상 행의 현재 주소를 포함합니다.

마이크로프로세서 아키텍처에서는 데이터 구조(스택)가 하드웨어 및 소프트웨어 수준에서 지원됩니다. 스택 작업을 위한 특수 명령어와 특수 레지스터가 있습니다. 스택은 더 작은 주소 쪽으로 채워집니다.

ESP/SP(스택 포인터 레지스터) – 등록하다 바늘 스택. 현재 스택 세그먼트의 스택 맨 위에 대한 포인터를 포함합니다.

EBP/BP(기본 포인터 레지스터) – 스택 베이스 포인터 레지스터. 스택 내부의 데이터에 대한 무작위 액세스를 구성하도록 설계되었습니다.

1.1.2. 세그먼트 레지스터

마이크로프로세서 소프트웨어 모델에는 6개의 세그먼트 레지스터: CS, SS, DS, ES, GS, FS. 이들의 존재는 Intel 마이크로프로세서의 특정 구성 및 RAM 사용으로 인해 발생합니다. 마이크로프로세서 하드웨어는 다음으로 구성된 프로그램의 구조적 구성을 지원합니다. 세그먼트.세그먼트 레지스터는 현재 사용 가능한 세그먼트를 나타내는 데 사용됩니다. 마이크로프로세서는 다음 세그먼트 유형을 지원합니다.

    코드 세그먼트.프로그램 명령이 포함되어 있습니다. 이 세그먼트에 액세스하려면 CS 레지스터(코드 세그먼트 레지스터)를 사용하십시오. 세그먼트 코드 레지스터. 여기에는 마이크로프로세서가 액세스할 수 있는 기계 명령 세그먼트의 주소가 포함됩니다.

    데이터 세그먼트.프로그램에서 처리한 데이터를 포함합니다. 이 세그먼트에 접근하려면 DS(데이터 세그먼트 레지스터) 레지스터를 사용하십시오. 세그먼트 데이터 레지스터, 현재 프로그램의 데이터 세그먼트 주소를 저장합니다.

    스택 세그먼트.이 세그먼트는 스택이라고 불리는 메모리 영역입니다. 마이크로프로세서는 먼저 "들어가는 것", 먼저 "나가는 것"이라는 원칙에 따라 스택을 구성합니다. 스택에 액세스하려면 SS(스택 세그먼트 레지스터) 레지스터를 사용합니다. 스택 세그먼트 레지스터, 스택 세그먼트의 주소를 포함합니다.

    추가 데이터 세그먼트.처리된 데이터는 세 개의 추가 데이터 세그먼트에 위치할 수 있습니다. 기본적으로 데이터는 데이터 세그먼트에 있는 것으로 간주됩니다. 추가 데이터 세그먼트를 사용하는 경우 해당 주소는 명령의 특수 세그먼트 재정의 접두사를 사용하여 명시적으로 지정되어야 합니다. 추가 데이터 세그먼트의 주소는 ES, GS, FS 레지스터(확장 데이터 세그먼트 레지스터)에 포함되어야 합니다.

        제어 및 상태 레지스터

마이크로프로세서에는 마이크로프로세서 자체와 명령이 현재 파이프라인에 로드된 프로그램의 상태에 대한 정보가 포함된 여러 레지스터가 포함되어 있습니다. 이것:

EIP/IP 명령어 포인터 레지스터;

    플래그 레지스터 EFLAGS/FLAGS.

이러한 레지스터를 사용하면 명령 실행 결과에 대한 정보를 얻을 수 있고 마이크로프로세서 자체의 상태에 영향을 줄 수 있습니다.

EIP/IP(명령 포인터 레지스터) – 바늘 . EIP/IP 레지스터는 32비트 또는 16비트 너비이며 현재 명령어 세그먼트에 있는 CS 세그먼트 레지스터의 내용을 기준으로 실행될 다음 명령어의 오프셋을 포함합니다. 이 레지스터는 직접 액세스할 수 없지만 점프 명령어를 사용하여 변경할 수 있습니다.

EFLAGS/FLAGS(플래그 레지스터) – 등록하다 깃발. 비트 크기는 32/16비트입니다. 이 레지스터의 개별 비트는 특정한 기능적 목적을 가지며 이를 플래그라고 합니다. 플래그는 어떤 조건이 충족되면 값 1("플래그 설정")을 취하고, 그렇지 않으면 값 0("플래그가 지워짐")을 갖는 비트입니다. 이 레지스터의 낮은 부분은 i8086의 FLAGS 레지스터와 완전히 유사합니다.

1.1.3 플래그 레지스터

플래그 레지스터는 32비트이며 이름은 EFLAGS입니다(그림 1). 레지스터의 개별 비트는 특정한 기능적 목적을 가지며 이를 플래그라고 합니다. 각각에는 특정 이름(ZF, CF 등)이 할당됩니다. EFLAGS의 하위 16비트는 i086 및 i286 마이크로프로세서용으로 작성된 프로그램을 실행할 때 사용되는 16비트 FLAGS 플래그 레지스터를 나타냅니다.

그림 1 플래그 레지스터

일부 플래그는 일반적으로 조건 플래그라고 합니다. 명령이 실행될 때 자동으로 변경되고 결과의 특정 속성(예: 0과 같은지 여부)을 기록합니다. 다른 플래그를 상태 플래그라고 합니다. 프로그램에서 변경되어 프로세서의 추가 동작에 영향을 줍니다(예: 인터럽트 차단).

조건 플래그:

CF(캐리 플래그) - 깃발을 들고. 정수를 더할 때 비트 그리드에 "맞지 않는" 캐리 단위가 나타나는 경우 또는 부호 없는 숫자를 뺄 때 첫 번째 숫자가 두 번째 숫자보다 작은 경우 값 1을 취합니다. Shift 명령에서는 비트 그리드 외부의 비트가 CF에 입력됩니다. CF는 곱셈 명령어의 기능도 포착합니다.

OF(오버플로 플래그) - 오버플로 플래그. 부호 있는 정수를 더하거나 뺄 때 결과가 절대값에서 허용 가능한 값을 초과하는 결과인 경우(가수가 오버플로되어 부호 숫자로 "등반")인 경우 1로 설정됩니다.

ZF(제로 플래그) - 제로 플래그. 명령 결과가 0이면 1로 설정됩니다.

SF(표시 플래그) - 깃발 징후. 부호 있는 숫자에 대한 연산이 음수 결과를 생성하는 경우 1로 설정됩니다.

PF(패리티 플래그) - 깃발 동등. 다음 명령의 결과에 짝수 개의 이진수가 포함되어 있으면 1과 같습니다. 일반적으로 I/O 작업에만 고려됩니다.

AF(보조 캐리 플래그) - 추가 캐리 플래그. 이진수에 대한 작업 수행 기능을 수정합니다.

상태 플래그:

DF(방향 플래그) - 방향 플래그. 선 명령에서 선을 보는 방향을 설정합니다. DF=0이면 선이 "앞으로"(처음부터 끝까지) 보이고, DF=1이면 반대 방향으로 보입니다.

IOPL(입력/출력 권한 수준) – I/O 권한 수준.작업 권한에 따라 I/O 명령에 대한 액세스를 제어하기 위해 마이크로프로세서 작동의 보호 모드에서 사용됩니다.

NT(중첩 작업) – 작업 중첩 플래그.한 작업이 다른 작업 내에 중첩되어 있다는 사실을 기록하기 위해 마이크로프로세서 작업의 보호 모드에서 사용됩니다.

시스템 플래그:

IF(인터럽트 플래그) - 인터럽트 플래그. IF=0이면 프로세서가 들어오는 인터럽트에 대한 응답을 중지하고, IF=1이면 인터럽트 차단이 제거됩니다.

TF(트랩 플래그) - 추적 플래그. TF=1일 때, 각 명령을 실행한 후 프로세서는 프로그램을 추적하기 위해 디버깅할 때 사용할 수 있는 인터럽트(1번)를 생성합니다.

RF(재개 플래그) – 재개 플래그. 디버그 레지스터에서 인터럽트를 처리할 때 사용됩니다.

VM(가상 8086 모드) – 가상 8086 플래그. 1-프로세서는 가상 8086 모드에서 작동하고, 0-프로세서는 실제 또는 보호 모드에서 작동합니다.

AC(정렬 확인) – 정렬 제어 플래그.메모리에 액세스할 때 정렬 제어를 허용하도록 설계되었습니다.

      기억의 조직.

마이크로프로세서가 접근할 수 있는 물리적 메모리를 램 (또는 랜덤 액세스 메모리 - 램). RAM은 고유한 주소(번호)를 갖는 바이트 체인입니다. 물리적.물리적 주소 값의 범위는 0~4GB입니다. 메모리 관리 메커니즘은 전적으로 하드웨어입니다.

마이크로프로세서 하드웨어는 RAM 사용에 대한 여러 모델을 지원합니다.

    분할된 모델. 이 모델에서 프로그램용 메모리는 연속적인 메모리 영역(세그먼트)으로 나누어지며, 프로그램 자체는 이러한 세그먼트에 있는 데이터에만 액세스할 수 있습니다.

    페이지 모델. 이 경우 RAM은 4KB의 고정 크기 블록 집합으로 간주됩니다. 이 모델의 주요 적용은 프로그램이 프로그램 실행을 위해 실제 메모리보다 더 많은 메모리 공간을 사용할 수 있도록 하는 가상 메모리 구성과 관련이 있습니다. Pentium 마이크로프로세서의 경우 가능한 가상 메모리 크기는 4TB에 달할 수 있습니다.

이러한 모델의 사용 및 구현은 마이크로프로세서의 작동 모드에 따라 다릅니다.

    실제 주소 모드(리얼 모드).모드는 i8086 프로세서의 작동과 유사합니다. 초기 프로세서 모델용으로 개발된 프로그램의 작동에 필요합니다.

    보호 모드.보호 모드에서는 멀티태스킹 정보 처리가 가능해지고, 4단계 권한 메커니즘과 페이징 구성을 사용하여 메모리를 보호할 수 있습니다.

    가상 8086 모드.이 모드에서는 i8086에 대한 여러 프로그램을 실행하는 것이 가능해집니다. 이 경우 리얼모드 프로그램이 동작할 수 있습니다.

분할은 여러 개의 독립적인 주소 공간이 존재하도록 보장하는 주소 지정 메커니즘입니다. 세그먼트는 독립적인 하드웨어 지원 메모리 블록입니다.

각 프로그램은 일반적으로 여러 세그먼트로 구성될 수 있지만 세 가지 주요 세그먼트(코드, 데이터, 스택)와 1~3개의 추가 데이터 세그먼트에 직접 액세스할 수 있습니다. 운영 체제는 RAM의 특정 물리적 주소에 프로그램 세그먼트를 배치한 다음 이러한 주소의 값을 적절한 레지스터에 배치합니다. 세그먼트 내에서 프로그램은 세그먼트의 시작 부분에 상대적인 주소에 선형적으로 액세스합니다. 즉, 주소 0에서 시작하여 세그먼트 크기와 동일한 주소로 끝납니다. 상대 주소 또는 편견,마이크로프로세서가 세그먼트 내의 데이터에 액세스하는 데 사용하는 것을 호출합니다. 효과적인.

리얼 모드에서 물리적 주소의 형성

리얼 모드에서 물리적 주소의 변경 범위는 0에서 1MB입니다. 최대 세그먼트 크기는 64KB입니다. 특정인에게 연락할 때 실제 주소 RAM은 세그먼트 시작 주소와 세그먼트 내 오프셋에 의해 결정됩니다. 세그먼트 시작 주소는 해당 세그먼트 레지스터에서 가져옵니다. 이 경우 세그먼트 레지스터에는 세그먼트 시작 부분의 물리적 주소 중 가장 중요한 16비트만 포함됩니다. 20비트 주소의 누락된 하위 4비트는 세그먼트 레지스터의 값을 4비트 왼쪽으로 이동하여 얻습니다. 시프트 작업은 하드웨어에서 수행됩니다. 결과 20비트 값은 세그먼트의 시작 부분에 해당하는 실제 물리적 주소입니다. 그건 실제 주소"세그먼트:오프셋" 쌍으로 지정됩니다. 여기서 "세그먼트"는 셀이 속한 메모리 세그먼트 시작 주소의 처음 16비트이고 "오프셋"은 이 셀의 16비트 주소입니다. 이 메모리 세그먼트의 시작(값 16 * 세그먼트 +오프셋은 셀의 절대 주소를 제공합니다). 예를 들어 CS 레지스터가 값 1234h를 저장하는 경우 주소 쌍 1234h:507h는 16*1234h+507h =12340h+507h = 12847h와 같은 절대 주소를 정의합니다. 이러한 쌍은 이중 단어로 작성되고 (숫자의 경우) "역전된" 형식으로 작성됩니다. 첫 번째 단어에는 오프셋이 포함되고 두 번째 단어에는 세그먼트가 포함되며 이러한 각 단어는 차례로 "거꾸로" 형태. 예를 들어, 1234h:5678h 쌍은 다음과 같이 작성됩니다. 78 | 56| 34 | 12|.

물리적 주소를 생성하는 이 메커니즘을 사용하면 소프트웨어를 재배치 가능하게 만들 수 있습니다. 즉, RAM의 특정 로딩 주소에 관계없이 독립적으로 만들 수 있습니다.

주제 2.5 프로세서 프로그래밍의 기초

프로그램의 길이가 길어질수록 다양한 작업의 코드를 기억하는 것이 점점 더 어려워집니다. 니모닉은 이와 관련하여 몇 가지 도움을 제공합니다.

기호 명령 코딩 언어를 호출합니다. 어셈블러.

어셈블리어각 발언이 정확히 하나의 기계 명령에 해당하는 언어입니다.

집회즉, 연산의 기호 이름을 기계어 코드로 바꾸고 기호 주소를 절대 또는 상대 숫자로 바꾸고, 라이브러리 프로그램을 통합하고 특정 매개변수를 지정하여 기호 명령어 시퀀스를 생성하여 기계어로 프로그램을 준비하는 것입니다. 마이크로 팀에서. 이 프로그램은 일반적으로 ROM에 있거나 일부 외부 미디어에서 RAM에 입력됩니다.

어셈블리 언어에는 고급 언어와 구별되는 몇 가지 기능이 있습니다.

1. 이는 어셈블리 언어 명령문과 기계 명령어 간의 일대일 대응입니다.

2. 어셈블리 언어 프로그래머는 대상 컴퓨터에 있는 모든 개체와 명령어에 액세스할 수 있습니다.

기계 지향 언어 프로그래밍의 기본을 이해하는 것은 다음과 같은 경우에 유용합니다.



PC 아키텍처에 대한 더 나은 이해와 컴퓨터의 보다 유능한 사용;

응용 문제를 해결하기 위한 프로그램을 위한 보다 합리적인 알고리즘 구조를 개발합니다.

소스 프로그램이 손실된 경우 고급 언어에서 컴파일된 .exe 및 .com 확장자를 사용하여 실행 가능한 프로그램을 보고 수정하는 기능(DEBUG 프로그램 디버거에서 지정된 프로그램을 호출하고 해당 디스플레이를 어셈블리에서 디컴파일함으로써) 언어);

가장 중요한 문제를 해결하기 위한 프로그램 컴파일(기계 지향 언어로 작성된 프로그램이 일반적으로 더 효과적입니다. 고급 언어 번역의 결과로 얻은 프로그램의 30-60%가 더 짧고 빠릅니다.)

사용되는 고급 언어나 OS 서비스 프로시저를 사용하여 구현할 수 없는 경우 기본 프로그램에 포함된 프로시저를 별도의 조각 형태로 구현합니다.

어셈블리 언어로 작성된 프로그램은 한 컴퓨터 계열에서만 실행될 수 있는 반면, 고급 언어로 작성된 프로그램은 잠재적으로 다른 컴퓨터에서 실행될 수 있습니다.

어셈블리 언어 알파벳은 ASCII 문자로 구성됩니다.

숫자는 정수일 뿐입니다. 다음이 있습니다:

이진수는 문자 B로 끝납니다.

문자 D로 끝나는 10진수

16진수는 문자 H로 끝납니다.

RAM, 레지스터, 데이터 프리젠테이션

특정 MP 시리즈의 경우 개별 프로그래밍 언어(어셈블리 언어)가 사용됩니다.

어셈블리어는 기계어와 고급언어의 중간 위치를 차지합니다. 이 언어로 프로그래밍하는 것이 더 쉽습니다. 어셈블리 언어 프로그램은 고급 언어 프로그램(프로그래머에게는 어셈블러보다 더 간단함)보다 특정 기계(좀 더 정확하게는 MP)의 기능을 더 효율적으로 사용합니다. MP KR580VM80의 ​​어셈블리 언어 예를 사용하여 기계 지향 언어 프로그래밍의 기본 원칙을 살펴 보겠습니다. 언어 프로그래밍에는 일반적인 방법론이 사용됩니다. 프로그램 녹화를 위한 특정 기술 기법은 대상 MP의 아키텍처 및 명령 시스템의 특징과 연관되어 있습니다.

MP KR580VM80 기반 마이크로프로세서 시스템의 소프트웨어 모델

그림 1에 따른 MPS의 소프트웨어 모델

MP 포트 메모리

에스 A.C.

그림 1

프로그래머의 관점에서 MP KR580VM80에는 다음과 같은 프로그램 액세스 가능 레지스터가 있습니다.

– 8비트 누산기 레지스터. MP의 주요 등록부입니다. ALU에서 수행되는 모든 작업에는 처리할 피연산자 중 하나를 누산기에 배치하는 작업이 포함됩니다. ALU에서의 연산 결과도 일반적으로 A에 저장됩니다.

비, 씨, 디, 이, H, 엘– 8비트 범용 레지스터(GPR). MP 내부 메모리. 처리된 정보와 작업 결과를 저장하도록 설계되었습니다. 16비트 단어를 처리할 때 레지스터는 BC, DE, HL 쌍을 형성하며 이중 레지스터를 첫 번째 문자(B, D, H)라고 합니다. 레지스터 쌍에서 가장 높은 것이 첫 번째 레지스터입니다. 레지스터 H와 L에는 데이터 저장과 RAM 셀의 16비트 주소 저장에 사용되는 특별한 속성이 있습니다.

플로리다– 플래그 레지스터(sign Register) MP에서 산술 및 논리 연산을 수행한 결과의 5개 부호가 저장되는 8비트 레지스터입니다. 그림에 따른 FL 형식

비트 C(CY - 캐리) - 캐리, 산술 연산을 수행할 때 바이트의 상위 순서에서 캐리가 있는 경우 1로 설정됩니다.

비트 P(패리티) – 패리티, 결과 비트의 1 수가 짝수이면 1로 설정됩니다.

AC 숫자는 결과의 하위 4차원 캐리지 값을 저장하도록 설계된 추가 캐리입니다.

비트 Z(0) - 연산 결과가 0이면 1로 설정됩니다.

비트 S(부호) – 결과가 음수이면 1로 설정되고 결과가 양수이면 0으로 설정됩니다.

SP– 스택에 삽입된 마지막 바이트가 기록된 메모리 셀의 주소를 저장하도록 설계된 16비트 레지스터인 스택 포인터.

RS– 프로그램 카운터(프로그램 카운터)는 실행될 다음 명령어의 주소를 저장하도록 설계된 16비트 레지스터입니다. 프로그램 카운터의 내용은 다음 명령어 바이트를 가져온 직후 자동으로 1씩 증가합니다.

주소 0000Н – 07FF의 초기 메모리 영역에는 제어 프로그램과 데모 프로그램이 포함되어 있습니다. ROM 영역입니다.

0800 – 0AFF - 연구 중인 프로그램을 기록하기 위한 주소 영역입니다. (램).

0В00 – 0ВВ0 - 데이터 쓰기를 위한 주소 영역입니다. (램).

0ВВ0 – 스택의 시작 주소. (램).

스택은 데이터 또는 주소의 임시 저장을 위해 특별히 구성된 RAM 영역입니다. 스택에 마지막으로 기록된 숫자가 먼저 팝됩니다. 스택 포인터는 정보가 기록되는 마지막 스택 셀의 주소를 저장합니다. 서브루틴이 호출되면 메인 프로그램으로의 복귀 주소가 자동으로 스택에 저장됩니다. 일반적으로 각 서브루틴이 시작될 때 실행과 관련된 모든 레지스터의 내용이 스택에 저장되고 서브루틴이 끝나면 스택에서 복원됩니다.

어셈블리 언어의 데이터 형식과 명령 구조

MP KR580VM80의 ​​메모리는 바이트라고 불리는 8비트 단어의 배열입니다. 각 바이트는 메모리 셀 시퀀스에서 위치를 결정하는 고유한 16비트 주소를 갖습니다. MP는 ROM과 RAM 모두에 포함될 수 있는 65536바이트의 메모리 주소를 지정할 수 있습니다.

데이터 형식

데이터는 8비트 단어로 메모리에 저장됩니다.

D7 D6 D5 D4 D3 D2 D1 D0

최하위 비트는 비트 0이고 최상위 비트는 비트 7입니다.

명령은 형식, 즉 명령에 할당된 비트 수로 특징지어지며, 이는 바이트 단위로 특정 기능 필드로 나뉩니다.

명령 형식

MP KR580VM80 명령은 1바이트, 2바이트 또는 3바이트 형식을 갖습니다. 멀티바이트 명령은 인접한 언어로 배치되어야 합니다. 명령 형식은 수행되는 작업의 세부 사항에 따라 다릅니다.

명령의 첫 번째 바이트에는 니모닉 형식으로 작성된 작업 코드가 포함됩니다.

이는 실행 중에 MP가 데이터에 대해 수행해야 하는 명령 형식과 작업, 주소 지정 방법을 결정하고 데이터 위치에 대한 정보도 포함할 수 있습니다.

두 번째 및 세 번째 바이트에는 연산이 수행되는 데이터 또는 데이터의 위치를 ​​나타내는 주소가 포함될 수 있습니다. 작업이 수행되는 데이터를 피연산자라고 합니다.

그림 2에 따른 단일 바이트 명령 형식

그림 4

어셈블리어 명령에서 연산 코드는 영어 단어를 간략하게 표현한 니모닉 표기법을 사용합니다. 니모닉(그리스 니모닉 - 암기 기술)을 사용하면 기능적 목적에 따라 명령을 더 쉽게 기억할 수 있습니다.

실행 전에 소스 프로그램은 어셈블러라는 번역 프로그램을 사용하여 코드 조합 언어, 즉 기계어로 번역되며, 이 형식으로 MP의 메모리에 배치된 다음 명령을 실행할 때 사용됩니다.


주소 지정 방법

모든 피연산자 코드(입력 및 출력)는 어딘가에 위치해야 합니다. MP의 내부 레지스터에 위치할 수 있습니다(가장 편리하고 빠른 옵션). 시스템 메모리에 위치할 수 있습니다(가장 일반적인 옵션). 마지막으로 I/O 장치에 위치할 수 있습니다(가장 드문 경우). 피연산자의 위치는 명령어 코드에 따라 결정됩니다. 명령어 코드가 입력 피연산자를 가져올 위치와 출력 피연산자를 배치할 위치를 결정할 수 있는 다양한 방법이 있습니다. 이러한 방법을 주소 지정 방법이라고 합니다.

MP KR580VM80의 ​​경우 다음과 같은 주소 지정 방법이 있습니다.

직접;

등록하다;

간접;

쌓였습니다.

직접 주소 지정에서는 (입력) 피연산자가 메모리에서 명령어 코드 바로 뒤에 위치한다고 가정합니다. 피연산자는 일반적으로 어딘가로 전송되거나 무언가에 추가되어야 하는 상수입니다. 데이터는 명령의 두 번째 또는 두 번째 및 세 번째 바이트에 포함되며 데이터의 하위 바이트는 명령의 두 번째 바이트에 있습니다. 세 번째 명령 바이트의 상위 바이트입니다.

똑바로 (일명 절대) 주소 지정은 피연산자(입력 또는 출력)가 메모리 주소의 주소에 있다고 가정합니다. 해당 코드는 프로그램 내부에서 명령 코드 바로 뒤에 위치합니다. 3바이트 명령에 사용됩니다.

등록하다 주소 지정에서는 피연산자(입력 또는 출력)가 MP의 내부 레지스터에 있다고 가정합니다. 단일 바이트 명령에 사용됨

간접 (암시적) 주소 지정은 MP의 내부 레지스터에 피연산자 자체가 아니라 메모리의 주소가 포함되어 있다고 가정합니다.

스택 주소 지정에서는 명령에 주소가 포함되어 있지 않다고 가정합니다. 16비트 SP 레지스터(스택 포인터)의 내용을 사용하여 메모리 셀 주소 지정.

명령 시스템

MP 명령 시스템은 MP가 수행할 수 있는 기본 작업의 전체 목록입니다. 이러한 명령으로 제어되는 MP는 기본 산술 및 논리 연산, 데이터 전송, 두 값 비교 등과 같은 간단한 작업을 수행합니다. MP KR580VM80의 ​​명령 수는 78개입니다(수정 244개 고려).

다음 명령 그룹이 구별됩니다.

데이터 전송;

산수;

두뇌티저;

점프 명령;

입력/출력, 제어 및 스택 명령.


명령어를 설명하거나 프로그램을 구성할 때 사용하는 기호 및 약어

상징 절감
주소 16비트 주소
데이터 8비트 데이터
데이터 16 16비트 데이터
포트 8비트 I/O 장치 주소
바이트 2 명령의 두 번째 바이트
바이트 3 명령의 세 번째 바이트
R, R1, R2 레지스터 중 하나: A, B, C, D, E, H, L
R.P. 레지스터 쌍 중 하나: B - BC 쌍을 지정합니다. D - DE 쌍을 지정합니다. H – HL 쌍을 지정합니다.
RH 쌍의 첫 번째 등록
R.L. 쌍의 두 번째 레지스터
Λ 논리적 곱셈
V 논리적 추가
덧셈 모듈로 2
주소가 레지스터 쌍 HL의 내용을 지정하는 메모리 셀, 즉 M = (HL)
공유하다