1 DATAS SEGMENT 2 str1 db 'it is a temp string',0ah, 0dh,'$' 3 str2 db 50 dup(?) 4 msg1 db 0ah,0dh,'source string:','$' 5 msg2 db 0ah,0dh,'distance sting:','$' 6 DATAS ENDS 7 8 STACKS SEGMENT 9 ;此處輸入堆棧段代碼 10 STACKS ENDS 11 12 CODES SEGMENT 13 ASSUME DS:DATAS,CS:CODES 14 START: 15 MOV AX,DATAS 16 MOV DS,AX 17 18 lea si,str1; 19 20 MOV ax,seg str2; 21 mov ES,AX; 22 lea di,str2; 23 24 mov CX,22; 25 again: 26 movsb; 27 loop again; 28 29 lea dx,msg1; 30 mov ah,09h; 31 INT 21H; 32 33 lea DX,str1; 34 mov ah,09h; 35 INT 21H; 36 37 lea dx,msg2; 38 mov ah,09; 39 INT 21H; 40 41 lea DX,str2; 42 mov ah,09h; 43 INT 21H; 44 45 mov ah,4ch; 46 INT 21h; 47 CODES ENDS 48 END START
以上代碼參考http://blog.csdn.net/u013507368/article/details/40859081。
匯編傳送指令參考http://www.doc88.com/p-296946327212.html
【1】0dh表示回車符號,這只是一個表示這一行終止的符號,不可見的,0Ah表示換行,就是跳轉到下一行,兩者用表示回車換行!
【2】DUP是數據定義偽指令,它可以按照給定的次數來復制某個(某些)操作數,可以避免多次鍵入同樣一個數據。例如 str1 db 6 dup(12H)和str1 db 12H,12H,12H,12H,12H,12H是等價的。問號是未初始化,不管它的值,只占用字節
【3】要用assume把段跟段寄存器對應起來的原因是原來的DOS找到的空閑內存的地址不是固定的,無法找到一個地址在任何時候都是空閑的。於是DOS需要可以重定位的程序,而當時的定位方式就是設置段寄存器的值使該程序能在可分配(空閑)的內存中可用。那就需要知道某個段被重定位時候需要修改哪個段寄存器的值才能正確執行。assume提供這種段和重定位代碼時需要對應修改的寄存器的關系給編譯器,編譯器再這個信息寫到二進制文件中去。比如DOS下的exe程序記錄在文件頭中。
【4】INT 21H是DOS功能調用,調用功能號放在AH中,使用格式如下:MOV AX fn; INT 21H.DOS系統功能調用參考:http://www.cnblogs.com/ynwlgh/archive/2011/12/12/2285017.html
【5】ES寄存器 附加段寄存器:定義附加段的起始地址。 程序中其他段得起始地址。 用於某些串操作中和DI寄存器相關聯 (ES)+(DI)=串地址的結尾。具體例子見https://zhidao.baidu.com/question/539021846.html
【6】MOVSB即字符串傳送指令,這條指令按字節傳送數據。通過SI和DI這兩個寄存器控制字符串的源地址和目標地址,比如DS:SI這段地址的N個字節復制到ES:DI指向的地址,復制后DS:SI的內容保持不變。
【7】變量的存儲包括段地址和偏移地址。SEG就是取段地址的。比如:
data segment
ore 10h
STRING db 'hello, world$'
data ends
假設data = 1234h,則:
mov di, seg string ;di = string所在段地址,即1234h
mov ei, offset string; ei = string偏移地址,即10h
