|
어셈블리어를 배우다가 다음 코드를 접했을 때, 저는 단순히 이 프로그램이 정상적으로 끝날 수 없다고 생각했습니다. 하지만 디버그 단일 단계 추적 후 프로그램이 정상적으로 종료될 수 있다는 것이 밝혀졌고, 이상한 현상이 발생했습니다: 프로그램이 코드:0005에서 코드:0014로 실행을 시작하자 jmp 명령어로 계속 코드:0008로 점프했습니다. 하지만 앞으로 한 걸음 계속 진행할 때, 프로그램은 코드:0 대신 코드:0(즉, S1 구간) 바로 점프합니다. 처음에는 무슨 일이 일어나고 있는지 이해하지 못했지만, 여러 번의 단번의 관찰 후에도 여전히 이상한 기분이 들었습니다. 교과서에서 JMP 명령어 사용법을 꼼꼼히 공부한 후[1], 그리고 기계어와 결합해 프로그램을 분석한 결과, JMP 명령어에 대해 새로운 이해를 갖게 되었습니다. 어셈블 코드 주소 오프셋(IP) 기계 명령어 CS:코드 (단위: H) 가정 코드 세그먼트 이동 액스, 4C00h 0000 B8004C 내부 21시간 0003 CD21 start: mov ax,0 0005 B80000 S: NOP 0008 90 NOP 0009 90 mov di, offset s 000A BF0800 mov si, offset s2 000D BE2000 mov ax,cs:[si] CS:0020=F6EB mov cs:[di],ax CS:0008=9090 s0: JMP 쇼트 S 0016 EBF0 S1: MOV AX,0 0018 B80000 int 21h 001B CD21 mov ax,0 001D B80000 s2: JMP 쇼트 S1 0020 EBF6 NOP 0022 90 코드 종료 엔드 시작 1. 다음 두 가지 사항을 명확히 이해해야 합니다 1. CPU 명령어 실행 과정은 다음과 같습니다: <1>. CS:IP가 가리키는 메모리 유닛에서 명령어를 읽고 명령어 버퍼에 넣습니다. <2>. IP=IP+현재 버퍼에 읽히는 명령어의 길이, 즉 IP가 다음 명령어를 가리킵니다. <3>. 버퍼에서 현재 명령을 실행하세요. <단계로 가세요> 2. 내부 세그먼트를 전송하는 jmp 단축 명령어의 의미 <1>. IP는 오프셋, 즉 IP = 지정자 주소 - jmp 명령 다음 첫 바이트의 주소입니다. <2>. 이 명령어의 기능은 IP의 값을 수정하는 것이며, 명령어를 실행한 후 IP = IP + 8비트 오프셋이 됩니다 < 3> 및 8비트는 변위 범위가 -128~127이며, 오프셋은 보집합 [2] 형태로 표현됩니다. 2. 코드 분석 1. 1단계: 프로그램은 입문 시작점(코드:0005)에서 실행을 시작하며, 코드:0013~0014 문구가 실행되면, 명문 jmp short S1의 기계어 코드가 S2 레이블에 복사되어 코드:0008로 복사되며, IP는 0016입니다. 이 시점에서 jmp short s 명령어가 없다고 가정하면, 프로그램은 s2:jmp short s1로 실행되고, jmp short s1을 명령어 버퍼에 읽고 IP=0022를 기록합니다; s2에서 s1로의 전송은 세그먼트 내 전송이며, 기계어 형식은 EB disp, disp=s1 지정-지정 s2=(00018-0022) 보완 =F6이므로 명령어 jmp short s1의 기계어는 EBF6이어야 합니다. 따라서 EBF6는 코드:0008~code:0009 단위로 복사됩니다. 2. 2단계: 명령어 jmp short s (EBF0)를 명령어 버퍼에 읽습니다, IP=IP+0002=0018; s-지정의 보수 코드는 s0=(0008-0018) = F0이며, s0에서 s로의 전송은 세그먼트 내 전송이며, 기계어 형식은 EB disp(즉, EBF0)입니다. 3. 3단계: 명령어 jmp short s(EBF0)는 명령어 EBF0, IP=IP+(s-지정명 s0)=0008, 코드:0008 유닛을 가리키는 명령어입니다. 4. 4단계: 유닛 코드 내용 읽기: 0008. s2에 있는 명령어 jmp short s1 (EBF6)이 code:0008~code:0009 유닛에 복사되므로, 유닛의 내용을 읽은 후 IP=IP+0002=000A 5. 5단계: 명령어 jmp short s1(EBF6)은 명령어 EBF6를 실행한 후 IP를 수정하는 명령으로, IP=IP+(s1-s2 지정)=0000, 코드:0000 유닛을 가리킵니다. 6. 6단계: 프로그램은 코드:0000으로 이동하여 실행, 즉 정상 종료가 완료됩니다. 3. 추신 이 코드를 올바르게 분석하세요: CPU 명령어 실행 과정과 JMP 단축 과정을 이해해야 하나요? (IP 수정으로 계산됨). 또한, 오프셋 계산 결과의 보완 코드도 하나의 키입니다. 이 겉보기에는 비정상적인 코드를 분석한 후, 어셈블리 내 JMP 명령어에 대해 더 깊이 이해하게 되었습니다.
|