어셈블리 언어 주소 문의

인터럽트 명령을 호출 한 후 사용 호출은 소스 오으로 돌아가려면 IRET 명령을 사용합니다!

소스 코드는 다음과

assume cs:code
code segment

	start:push cs
		  pop ds
		  
		  mov ax,0
		  mov es,ax
		  
		  mov si,offset setscreen
		  mov di,200h
		  mov cx,offset screenend-setscreen;设置cx为传输长度
		  cld;
		  ;将代码从ds:[si]传送到es:[di]
		  rep movsb
		  
		  mov ax,0
		  mov es,ax
		  mov word ptr es:[7ch*4],200h
		  mov word ptr es:[7ch*4+2],0
		  ;将起始地址放入中断向量中
		  
		  mov ax,4c00h
		  int 21h
		;debug技巧:先运行中断之后再debug
		;测试的t32.exe
	
setscreen:jmp short set
		  
	table dw sub1,sub2,sub3,sub4
	
	set  :push bx
		  
		  cmp ah,3
		  ja sret
		  ;判断功能号是否大于3
		  ;大于3时直接返回
		  
		  mov bl,ah
		  mov bh,0
		  add bx,bx;根据ah中的功能
		  ;计算对应子程序在table表中的
		  ;偏移量
		  ;ip = 0216
		  
		  mov ax,table
		  call word ptr table[bx]
		  ;调用对应的功能子程序
		  
	sret :pop bx
		  ret
   setend:nop
   
     sub1:push bx
		  push cx
		  push es
		  mov bx,0b800h
		  mov es,bx
		  mov cx,2000
		  
	sub1s:mov byte ptr es:[bx],' '
		  add bx,2
		  loop sub1s
		  
		  pop es
		  pop cx
		  pop bx
		  ret
		  
	 sub2:;运行02时应该跳入到
		  ;sub2程序中,但是该程序没有
	      push bx
		  push cx
		  push es
		  
		  mov bx,0b800h
		  mov es,bx
		  mov bx,1
		  mov cx,2000
		  ;定位到显存区域及设置循环次数
		  
	sub2s:and byte ptr es:[bx],11111000b
		  or es:[bx],al
		  add bx,2
		  loop sub2s
		  ;设置第0,1,2位的前景色
		  
		  pop es
		  pop cx
		  pop bx
		  ret
		  
	 sub3:push bx
		  push cx
		  push es
		  ;压栈保存数据
		  
		  mov cl,4
		  mov al,02h
		  shl al,cl
		  mov bx,0b800h
		  mov es,bx
		  mov bx,1
		  mov cx,2000
		  
		  
	sub3s:and byte ptr es:[bx],10001111b
		  or es:[bx],al
		  add bx,2
		  loop sub3s
		  
		  pop es
		  pop cx
		  pop bx
		  ret 
		  ;出栈恢复数据
		  
	 sub4:push cx
		  push si
		  push di
		  push es
		  push ds
		  
		  mov si,0b800h
		  mov es,si
		  mov ds,si
		  mov si,160
		  mov di,0
		  cld
		  mov cx,24
		  ;共复制最后一行
		  
	sub4s:push cx
		  mov cx,160
		  rep movsb
		  pop cx
		  loop sub4s
		  
		  mov cx,80
		  mov si,0
		  
   sub4s1:mov byte ptr [160*24+si],' '
		  add si,2
		  loop sub4s1
		  ;最后一行清空
		  
		  pop ds
		  pop es
		  pop di
		  pop si
		  pop cx
		  ret 
screenend:nop
code ends
end start

0000이 시점보기에서 : 다음의 내용의 0200 부분을
그림 삽입 설명 여기다음과 같이 코드의 시작 부분에서 중단되어야한다 :

JMP 짧은 세트

table dw sub1,sub2,sub3,sub4
;0051,0069,0087,00AB

;下面三条对应的机器码:5380,
;03fc,1377,之前使用u命令时翻译错误

;u0000:020a开始翻译指令
set  :push bx
	  
	  cmp ah,3
	  ja sret
	  ;判断功能号是否大于3
	  ;大于3时直接返回

완벽에 해당되지 않음이 때문에 분해 전위의 디버그입니다
0200 0000 : u0000의 SUB1, SUB2, SUB3, SUB4의 0051,0069,0087,00ab 0202 시작
오프셋 대응 원래 동안 분해 형식은 중단
분해 시작 020A : 0000에서 다음에게 우리를
그림 삽입 설명 여기
혼란 가끔 포맷 할 때 발생할 수 분해 볼, 단지 어셈블리 코드로 형식이 경우의 대응을
그림 삽입 설명 여기
시작 위치를 실행 테이블 명령을 어드레스 020A의 JMP, 즉 0000 : 0202
0202 + 0000 = 51H : 오프셋 SUB1 0000에 대응하는 오프셋 어드레스 환산 테이블을 기준으로 0253,
0000 : SUB1의 동작 개시 위치 0253 코드
그러나 아 해결하지 않는 이유는 무엇입니까? ? ? 어떻게 주소를 잘 작성하지 않은 계산? ? ?
정보에 액세스
밝혀졌다, 프로그램은 컴파일시에 컴파일러는 그림과 같이 좋은 주소 라벨 계산했습니다 005F, 007A, 0098,00BA, 새로운 인터럽트 루틴을로드 할 때와 CS를 다시 IP 값이지만 기준 오프셋 어드레스가 변경, 따라서 잘못된 위치를 가리키는. 다음과 같이 우리는 조직 지시어는 주소 레이블을 다시 계산하도록 컴파일러에 지시 사용할 수 있으며, 변경 사항은 다음과 같습니다
그림 삽입 설명 여기
마지막으로 주소의 문제를 해결 얽힌 버그 나 너무 오래에!

게시 17 개 원래 기사 · 원 찬양 7 · 전망 2978

추천

출처blog.csdn.net/znevegiveup1/article/details/103891036