1. 程式人生 > >組合語言實現功能(2)資料複製的實現

組合語言實現功能(2)資料複製的實現

問題1:將記憶體ffff:0~ffff:b單元中的資料複製到0:200~0:20b單元中

分析

1、0:200~0:20b單元如何表示

  • 0020:0~0020:b可以等同於以上單元,而且單元的偏移地址是從0開始,和需要複製的單元相同

2、單元中的資料能直接進行復制轉移嗎

  • 不可以,需要用暫存器進行中轉
assume cs:code
code segment

;做法一
;-----------------------------
	mov bx,0		;因為資料來源和去處的偏移地址相同,用bx同意代替
	mov cx,12


s:	mov ax,offffh	;因為需要重複利用ax,所以需要迴圈設定
	mov ds,ax
	mov dl,ds:[bx]	;將資料複製到dx的低8位中

	mov ax,0020h
	mov ds,ax
	mov ds:[bx],dl	;將資料複製到指定的記憶體單元中

	inc bx			;向下一個單元移動
	loop s

;-----------------------------

;做法二,上一個做法需要重複設定ds,這裡可改進
;-----------------------------
	mov ax,0ffffh
	mov ds,ax

	mov ax 0020h
	mov es,ax

	mov bx,0
	mov cx,12

s:	mov dl,ds:[bx]
	mov es:[bx],dl
	inc bx
	loop s

;-----------------------------

	mov ax,4c00h
	int 21h

code ends
end

問題2:將“mov ax,4c00h“之前的指令複製到記憶體0:200處

分析:

1、如何知道程式碼的起始地址

  • 利用cs指向的就是程式碼的開始地址

2、如何知道程式碼的長度

  • 可以使用(offset 標號)之間相減得出程式碼的長度
assume cs:code
code segment
start:	        mov ax,cs
	 	mov ds,ax
		mov ax,0020h
		mov es,ax	;設定複製資料的來源和去處

		mov bx,0
		mov cx,offset last-offset start	  ;設定程式碼的長度

s:		mov al,ds:[bx]
		mov es:[bx],al	;實現資料的轉移
		inc bx
last:           loop s

		mov ax,4c00h
		int 21h
code ends
end

問題3:將程式中定義的資料逆序存放

分析:

如何實現逆序

  • 利用棧的特性實現
assume cs:code
code segment
	dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
	dw 16 dup(0)	;棧空間的使用

start: 	mov ax,cs
		mov ss,ax
		mov sp,30h	;棧空間是從後往前新增,棧頂指向30h

		mov bx,0
		mov cx,8

s:		push cs:[bx]
		add bx,2
		loop s		;將資料段中的0~15單元中的資料壓入棧中

		mov bx,0
		mov cx,8

s0:		pop cs:[bx]
		add bx,2
		loop s0		;依次出棧8個字型資料

		mov ax,4c00h
		int 21h

code ends
end start

改進版:以上程式中的內容沒有分段儲存,可改進

assume cs:code,ds:data,ss:stack
date segment
	dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
date ends

stack segment
	dw 16 dup(0)	;棧空間的使用
stack ends

code segment
start:	mov ax,stack
		mov ss,ax
		mov sp,20h	;棧開始的地址已經不包括data段的內容,則為20h

		mov ax,data
		mov ds,ax

		mov bx,0
		mov cx,8

s:		push ds:[bx]
		add bx,2
		loop s

		mov bx,0
		mov cx,8

s0:		pop ds:[bx]
		add bx,2
		loop s0

		mov ax,4c00h
		int 21h
code ends

end start

問題4:將字串”welcome to masm”複製到它後面的資料區中

分析

1、要複製到資料在哪裡

  • 資料的起始地址在data:0

2、要複製到哪裡去

  • 複製的資料長度是16個位元組,後面的資料區的偏移地址就是16

3、一共複製了幾次

  • 因為使用的是16位暫存器,一次可以傳輸兩個位元組,所以只需要執行8次
assume cs:code,ds:data

data segment
	db 'welcome to masm!'
	db 16 dup(0)
data ends

code segment
start:	mov ax,data
		mov ds,ax
		mov si,0	;設定資料來源的起始位置
		mov di,16	;設定資料去處的起始位置

		mov cx,8	;用暫存器進行復制,只需要8次
s:		mov ax,ds:[si]
		mov ds:[di],ax
		add si,2
		add di,2
		loop s

		mov ax,4c00h
		int 21h
code ends

end