어셈블러는 프로그램 자체 코드 세그먼트의 16 진수 값을 지정된 메모리 영역에 복사합니다.

완전한 소스 프로그램을 작성하려면 먼저 프로그램 코드 세그먼트의 길이 인 변수 배열을 정의하고 코드 세그먼트를 배열에 복사하십시오.

레이블을 사용하여 코드 길이 확인

어셈블리 언어의 루프 명령에서 루프 명령은 cx 레지스터의 값에 따라 루프 명령문을 실행할지 여부를 결정합니다. 루프 뒤에는 메모리의 명령 주소를 나타내는 s와 같은 레이블이옵니다. 실제로 컴파일러는 마지막에 s 레이블을 메모리 주소로 변환합니다.

레이블은 메모리 주소이므로 두 레이블을 정의하고 두 레이블 간의 차이를 사용하여 두 레이블 간의 명령 바이트 수를 계산할 수 있습니다. 따라서이 프로그램에서 처음 명령은 "시작"레이블로 설정되고 마지막 명령은 "중지"레이블로 설정되며 복사 할 명령의 바이트 수는 "중지-시작"입니다.

포털
(1) 예비 코드 :
여기에 사진 설명 삽입

(2) 실행 전 어레이의 데이터
여기에 사진 설명 삽입

(3) 어셈블리 코드의 이진 값
여기에 사진 설명 삽입

(4) 작업이 끝난 후 쓰기 상황을 관찰하십시오.
여기에 사진 설명 삽입

1. 비교해 보면 프로그램 코드 세그먼트가 완전히 작성되었음을 알 수 있습니다.

2. 미리 신청 한 공간 아래에 데이터가 기록되어있는 것으로 나타 났는데 그 이유는 무엇입니까?
 디버깅 :
프로그램 초기화를 시작할 때 아래 데이터 영역이 채워지 것으로 나타났습니다.
여기에 사진 설명 삽입

그러나 프로그램이 코드의 모든 이진 값을 배열에 복사 한 후에는 종료되어야하지만 여전히 메모리에 기록합니다.
여기에 사진 설명 삽입

내 프로그램이 얼마나 큰지 모르기 때문에 배열의 크기를 무조건 추측하지만 OD로 끌어 와서 계산 된 것을 알았습니다. 이때 조립 환경으로 돌아가서 변경합니다. OD 계산에 대한 어레이의 크기 값.
다음 값은 프로그램 실행 중에 여전히 수정되는 것으로 밝혀졌으며 프로그램은 매번 4 바이트를 복사하지만 28 번 반복됩니다. 동시에 코드 영역에서 총 27 바이트의 데이터를 발견하여 더 많이 복사했습니다. 정확한 복사를 위해 한 번에 1 바이트 씩 27 번 복사하고 코드를 수정합니다.

수정 된 코드는 완벽하며 +1 연산으로 인해 코드가 짧아집니다.

(1) 최종 코드
여기에 사진 설명 삽입

(2) 쓰기 전 어레이의 데이터
여기에 사진 설명 삽입

(3) 16 진수 코드
여기에 사진 설명 삽입

(4) 쓰기 후 배열
여기에 사진 설명 삽입

더 이상 사본이 없음을 발견했습니다. 완벽합니다! 조금 느리지 만. 사실 한 번에 여러 바이트를 복사 할 수 있고 결국 판단하고 나머지를 복사해야하지만 게으 르기 때문에 작성하지 않습니다.

	.386
	.model flat,stdcall
	option casemap:none
	include kernel32.inc
	includelib kernel32.lib
	include Stdlib.Inc
	includelib Stdlib.lib
	.data
	myself  db 23 dup(2)
	.code
	.startup CONSOLE
	
star:	mov ecx , offset stop - offset star
	mov eax , offset myself
	mov ebx , offset star
s:	mov dl , [ebx]
	mov [eax] , dl
	inc ebx
	inc eax
	loop s
stop:	
	.exit
	end

추천

출처blog.csdn.net/weixin_45715236/article/details/115018470