アセンブリ言語のアドレス問い合わせ

元オハイオ州に戻るには、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スタート
、対応するオフセットオリジナルながら、分解フォーマットは、破砕
0000から次に我々が:分解開始020A
ここに画像を挿入説明
混乱が時々フォーマット起こり得る場合に分解見だけアセンブリコードに形式にこの場合対応する、
ここに画像を挿入説明
開始位置を実行表命令アドレス020AのJMP、すなわち0000:0202
:+ 51H = 0000 0202:オフセットは、オフセット、アドレス対応SUB1 0000の点でテーブルに対するものである 、0253
0000から:SUB1の動作開始位置0253コードは、
しかし、ああ対処しないのですか?アドレスを計算する方法右ではありませんか?
情報へのアクセス
が判明したが、プログラムはコンパイル時にコンパイラは、図に示す良いアドレスラベルを計算した:005F、007A、0098,00BA、新しい割り込みルーチンのロード時とCSをリセットし、IP値が、基準オフセットアドレスが変更されているが、このように間違った場所を指しています。私たちは、ORGディレクティブは、住所ラベルを再計算するようにコンパイラーに指示します使用することができ、変更内容は次の通りです:
ここに画像を挿入説明
もつれたバグが、私はそう長く最後にアドレスの問題を解決するために!

公開された17元の記事 ウォン称賛7 ビュー2978

おすすめ

転載: blog.csdn.net/znevegiveup1/article/details/103891036