32位匯編語言程序設計 第3版 課件 錢曉捷 第5-9章 模塊化程序設計-浮點、多媒體及64位指令_第1頁
32位匯編語言程序設計 第3版 課件 錢曉捷 第5-9章 模塊化程序設計-浮點、多媒體及64位指令_第2頁
32位匯編語言程序設計 第3版 課件 錢曉捷 第5-9章 模塊化程序設計-浮點、多媒體及64位指令_第3頁
32位匯編語言程序設計 第3版 課件 錢曉捷 第5-9章 模塊化程序設計-浮點、多媒體及64位指令_第4頁
32位匯編語言程序設計 第3版 課件 錢曉捷 第5-9章 模塊化程序設計-浮點、多媒體及64位指令_第5頁
已閱讀5頁,還剩272頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

32位匯編語言程序設計第5章模塊化程序設計5.1子程序結構5.2參數(shù)傳遞5.3多模塊程序結構5.4宏結構第5章模塊化程序設計以子程序結構為主體,圍繞數(shù)碼轉換實現(xiàn)鍵盤輸入和顯示輸出掌握子程序、文件包含、宏匯編等各種多模塊編程的方法45.1子程序結構經常用到的應用問題編寫成一個通用子程序大型處理過程分解成能夠解決的模塊使用子程序可以使程序的結構更為清楚程序的維護更為方便有利于大程序開發(fā)時的多個程序員分工合作子程序(Subroutine)=函數(shù)(Function)=過程(Procedure)55.1.1子程序指令子程序與主程序分開、完成特定功能的一段程序主程序(調用程序)執(zhí)行調用指令CALL調用子程序子程序(被調用程序)執(zhí)行返回指令RET返回主程序CALLlabel主程序RET子程序回到CALL指令后的指令處61.子程序調用指令CALLCALL指令用在主程序中,實現(xiàn)子程序的調用分成段內調用(近調用)和段間調用(遠調用)目標地址采用相對尋址、直接尋址或間接尋址入棧返回地址:將CALL下條指令的地址壓入堆棧

CALLlabel ;調用標號指定的子程序

CALLreg32/reg16

;調用寄存器指定地址的子程序

CALLmem48/mem32/mem16 ;調用存儲單元指定地址的子程序72.子程序返回指令RETRET指令用在子程序結束,實現(xiàn)返回主程序

RET

;無參數(shù)返回:出棧返回地址

RETi16 ;有參數(shù)返回:出棧返回地址

;ESP←ESP+i16MASM會根據(jù)存儲模型等信息確定子程序的遠近調用,并相應產生返回指令8name …

RET

CALLnamenext:… ;下條指令CALL的調用和RET的返回主程序子程序堆棧next;思考如下代碼片段的功能 callnextnext: popeax

;EAX=?93.過程定義偽指令MASM利用過程定義偽指令獲得子程序信息

過程名 PROC

…… ;過程體

過程名 ENDP

;過程名為符合語法的標識符PROC后面可加參數(shù):NEAR或FAR簡化段定義源程序格式中,通常不需指定10〔例5-1〕子程序調用程序-1

;代碼段,主程序00000000 B800000001

moveax,100000005 BD00000005

movebp,50000000A E800000016

callsubp

;子程序調用0000000F B900000003 retp1: movecx,300000014 BA00000004 retp2: movedx,400000019 E800000000E

calldisprd11〔例5-1〕子程序調用程序-2 ;代碼段,子程序subp proc ;過程定義,過程名為subp

pushebp

mov

ebp,esp

movesi,[ebp+4] ;ESI=CALL下條指令(標號RETP1)偏移地址

mov

edi,offsetretp2 ;EDI=標號RETP2的偏移地址

movebx,2

popebp ;彈出堆棧,保持堆棧平衡

ret ;子程序返回subp

endp ;過程結束MOV[EBP+4],EDI?示意圖12子程序調用的堆棧返回135.1.2子程序設計子程序的編寫方法與主程序一樣但需要留意幾個問題:利用過程定義,獲得子程序名和調用屬性RET指令返回主程序,CALL指令調用子程序壓入和彈出操作要成對使用,保持堆棧平衡開始保護寄存器,返回前相應恢復安排在代碼段的主程序之外子程序允許嵌套和遞歸最好有完整的注釋難點是參數(shù)傳遞14〔例5-2〕回車換行子程序dpcrlf proc ;回車換行子程序

pusheax ;保護寄存器

moval,0dh ;輸出回車字符

calldispc ;子程序中調用子程序,實現(xiàn)子程序嵌套

moval,0ah ;輸出換行字符

calldispc

popeax ;恢復寄存器

ret ;子程序返回dpcrlf

endp155.2參數(shù)傳遞主程序與子程序間通過參數(shù)傳遞建立聯(lián)系入口參數(shù)(輸入參數(shù)):主程序→子程序出口參數(shù)(輸出參數(shù)):子程序→主程序傳遞參數(shù)的多少反映程序模塊間的耦合程度參數(shù)的具體內容數(shù)據(jù)本身(傳遞數(shù)值)數(shù)據(jù)的存儲地址(傳遞地址,傳遞引用)參數(shù)傳遞方法寄存器變量堆棧165.2.1寄存器傳遞參數(shù)最簡單和常用的參數(shù)傳遞方法把參數(shù)存于約定的寄存器少量數(shù)據(jù)直接傳遞數(shù)值大量數(shù)據(jù)只能傳遞地址帶有出口參數(shù)的寄存器不能保護和恢復帶有入口參數(shù)的寄存器可以保護、也可以不保護,但最好能夠保持一致17〔例5-3〕十六進制顯示程序-1

mov

eax,1234abcdh ;假設一個數(shù)據(jù)

xor

ebx,ebx

movecx,8 ;8位十六進制數(shù)again: roleax,4 ;高4位循環(huán)移位進入低4位

pusheax ;mov

edx,eax

callhtoasc ;調用子程序

movregd+4[ebx],al ;保存轉換后的ASCII碼

popeax ;mov

eax,edx

incebx

dec

ecx

jnzagain

mov

eax,offset

regd calldispmsg ;顯示regddb'EAX=',8dup(0),'H',018〔例5-3〕十六進制顯示程序-2

;子程序htoasc proc

;將AL低4位表達的一位十六進制數(shù)轉換為ASCII碼

andal,0fh ;只取AL的低4位

oral,30h ;AL高4位變成3

cmpal,39h ;是0~9,還是A~F

jbe

htoend

addal,7 ;是A~F,ASCII碼再加上7htoend:

ret ;子程序返回htoasc

endp19〔例5-3〕十六進制顯示程序-3

;子程序htoasc proc

andeax,0fh ;取AL低4位

mov

al,ASCII[eax] ;換碼

ret ;子程序的局部數(shù)據(jù)(只讀)ASCII db'0123456789ABCDEF'htoasc

endpEAX=1234ABCDH運行結果20〔例5-4〕有符號十進制數(shù)顯示程序-1轉換的算法如下:

1)首先判斷數(shù)據(jù)是零、正數(shù)或負數(shù),是零顯示“0”退出 2)是負數(shù),顯示負號“-”,求數(shù)據(jù)的絕對值 3)接著數(shù)據(jù)除以10,余數(shù)為十進制數(shù)碼,加30H轉換為ASCII碼保存 4)重復第(3)步,直到商為0結束 5)依次從高位開始顯示各位數(shù)字21〔例5-4〕有符號十進制數(shù)顯示程序-2

;數(shù)據(jù)段array dd1234567890,-1234,0,1,...count equ($-array)/4writebuf db12dup(0) ;顯示緩沖區(qū)

;代碼段

mov

ecx,count

movebx,0again: mov

eax,array[ebx*4] ;EAX=入口參數(shù)

callwrite ;調用子程序,顯示一個數(shù)據(jù)

calldispcrlf ;換行以便顯示下一個數(shù)據(jù)

incebx

dec

ecx

jnzagain寄存器傳遞參數(shù)22〔例5-4〕有符號十進制數(shù)顯示程序-3 ;顯示有符號十進制數(shù)的子程序write proc ;EAX=入口參數(shù)

pushebx ;保護寄存器

pushecx pushedx

mov

ebx,offset

writebuf ;EBX指向顯示緩沖區(qū)

testeax,eax ;判斷數(shù)據(jù)是零、正數(shù)或負數(shù)

jnzwrite1 ;不是零,跳轉

movbyteptr[ebx],'0' ;是零,設置“0”

incebx

jmpwrite5 ;轉向顯示write1: jnswrite2 ;是正數(shù),跳轉寄存器傳遞參數(shù)23〔例5-4〕有符號十進制數(shù)顯示程序-4

movbyteptr[ebx],'-';是負數(shù),設置負號

incebx

neg

eax ;數(shù)據(jù)求補(絕對值)write2: movecx,10

pushecx ;10壓入堆棧,作為退出標志write3: cmpeax,0 ;數(shù)據(jù)(商)為零,轉向保存

jzwrite4

xor

edx,edx ;零位擴展被除數(shù)為EDX.EAX

divecx ;數(shù)據(jù)除以10:EDX.EAX÷10

addedx,30h ;余數(shù)(0~9)轉換為ASCII碼

pushedx ;數(shù)據(jù)先低位后高位壓入堆棧

jmpwrite324〔例5-4〕有符號十進制數(shù)顯示程序-5write4: popedx ;數(shù)據(jù)先高位后低位彈出堆棧

cmp

edx,ecx ;是結束標志10,轉向顯示

jewrite5

mov[ebx],dl ;數(shù)據(jù)保存到緩沖區(qū)

incebx

jmpwrite4write5: movbyteptr[ebx],0 ;顯示內容加上結尾標志

mov

eax,offset

writebuf calldispmsg

popedx ;恢復寄存器

popecx popebx

ret ;子程序返回write endp255.2.2共享變量傳遞參數(shù)子程序和主程序使用同一個變量名存取數(shù)據(jù)如果變量定義和使用不在同一個程序模塊中,需要利用PUBLIC、EXTREN聲明共享變量傳遞參數(shù),子程序的通用性較差特別適合在多個程序段間、尤其在不同的程序模塊間傳遞數(shù)據(jù)26〔例5-5〕二進制輸入程序-1

;數(shù)據(jù)段count equ5array ddcountdup(0)temp dd0 ;共享變量

;代碼段,主程序

mov

ecx,count

mov

ebx,offsetarrayagain: callrdbd

;調用子程序,輸入一個數(shù)據(jù)

mov

eax,[temp]

;獲得出口參數(shù)

mov[ebx],eax

;存放到數(shù)據(jù)緩沖區(qū)

addebx,4 loopagain共享變量傳遞參數(shù)27〔例5-5〕二進制輸入程序-2

;代碼段,子程序rdbd proc

;二進制輸入子程序

pusheax

;出口參數(shù):共享變量TEMP

pushebx pushecxrdbd1: xor

ebx,ebx

;EBX用于存放二進制結果

movecx,32

;限制輸入字符的個數(shù)rdbd2: callreadc

;輸入一個字符

cmpal,'0'

;檢測鍵入字符是否合法

jb

rderr

;不合法則返回重新輸入

cmpal,'1'

ja

rderr28〔例5-5〕二進制輸入程序-3

subal,'0'

;對輸入的字符進行轉化

shlebx,1

;EBX的值乘以2

orbl,al

;BL和AL相加

looprdbd2

;循環(huán)鍵入字符

mov

[temp],ebx

;把二進制結果存放TEMP返回

calldispcrlf

;分行

popecx popebx popeax

ret共享變量傳遞參數(shù)29〔例5-5〕二進制輸入程序-4rderr: mov

eax,offset

errmsg ;顯示錯誤信息

calldispmsg

jmprdbd1errmsg db0dh,0ah,'Inputerror,enteragain:',0rdbd

endp30〔例5-6〕有符號十進制數(shù)輸入程序-1十進制有符號整數(shù)轉換為補碼的算法如下: 1)判斷輸入了正數(shù)、還是負數(shù),用一個寄存器記錄 2)判斷下一個字符是否為有效數(shù)碼 字符無效,提示錯誤重新輸入,并轉向(1) 字符有效,繼續(xù) 3)字符有效,減30H轉換為二進制數(shù);然后將前面輸入的數(shù)值乘10,并與剛輸入的數(shù)字相加得到新的數(shù)值 4)判斷輸入的數(shù)據(jù)是否超出有效范圍超出范圍,提示錯誤重新輸入,并轉向(1)沒有超出范圍,則繼續(xù) 5)重復第(2)~(4)步,輸入字符都有效,一直處理完 6)是負數(shù)進行求補,轉換成補碼;否則直接將數(shù)值保存31〔例5-6〕有符號十進制數(shù)輸入程序-2

;數(shù)據(jù)段count equ10array ddcountdup(0)temp dd0readbuf db30dup(0) ;代碼段

mov

ecx,count

mov

ebx,offsetarrayagain: callread ;調用子程序,輸入一個數(shù)據(jù)

mov

eax,[temp] ;獲得出口參數(shù)

mov[ebx],eax ;存放到數(shù)據(jù)緩沖區(qū)

addebx,4

dec

ecx

jnzagain共享變量傳遞參數(shù)32〔例5-6〕有符號十進制數(shù)輸入程序-3 ;輸入有符號十進制數(shù)的子程序read proc ;出口參數(shù):變量TEMP=補碼表示的二進制數(shù)值

pusheax ;說明:負數(shù)用“-”引導

pushebx

pushecx pushedxread0: mov

eax,offset

readbuf

callreadmsg ;輸入一個字符串

testeax,eax

jz

readerr ;沒有輸入數(shù)據(jù),錯誤

cmpeax,12

ja

readerr ;輸入超過12個字符,錯誤33〔例5-6〕有符號十進制數(shù)輸入程序-4

mov

edx,offset

readbuf;EDX指向輸入緩沖區(qū)

xor

ebx,ebx ;EBX保存結果

xor

ecx,ecx ;ECX為正負標志,0為正,-1為負

mov

al,[edx] ;取一個字符

cmpal,'+' ;是“+”,繼續(xù)

jzread1

cmpal,'-' ;是“-”,設置-1標志

jnzread2

movecx,-1read1: incedx ;取下一個字符

mov

al,[edx]

testal,al ;是結尾0,轉向求補碼

jzread334〔例5-6〕有符號十進制數(shù)輸入程序-5read2: cmpal,'0' ;不是0~9之間的數(shù)碼,錯誤

jb

readerr

cmpal,'9'

ja

readerr subal,30h ;是0~9之間的數(shù)碼,轉換

imulebx,10 ;原數(shù)值乘10:EBX=EBX×10

jc

readerr ;CF=1,乘積溢出,出錯

movzx

eax,al ;零位擴展,便于相加

addebx,eax ;原數(shù)乘10后,與新數(shù)碼相加

cmpebx,80000000h ;數(shù)據(jù)超過231,出錯

jberead1 ;繼續(xù)轉換下一個數(shù)位35〔例5-6〕有符號十進制數(shù)輸入程序-6readerr: mov

eax,offset

errmsg ;顯示出錯信息

calldispmsg

jmpread0 ;read3: testecx,ecx ;判斷是正數(shù)還是負數(shù)

jzread4

neg

ebx ;是負數(shù),進行求補

jmpread5read4: cmpebx,7fffffffh ;正數(shù)超過231-1,出錯

ja

readerr36〔例5-6〕有符號十進制數(shù)輸入程序-7read5: mov

[temp],ebx ;設置出口參數(shù)

popedx popecx popebx popeax

ret ;子程序返回errmsg db'Inputerror,enteragain:',0read endp共享變量傳遞參數(shù)375.2.3堆棧傳遞參數(shù)主程序將入口參數(shù)壓入堆棧,子程序從堆棧中取出參數(shù)出口參數(shù)通常不使用堆棧傳遞高級語言進行函數(shù)調用時提供的參數(shù),實質也利用堆棧傳遞采用堆棧傳遞參數(shù)是程式化的,它是編譯程序處理參數(shù)傳遞、以及匯編語言與高級語言混合編程時的常規(guī)方法38〔例5-7〕計算有符號數(shù)平均值程序-1

;數(shù)據(jù)段array dd675,354,-34,...count equ($-array)/4 ;代碼段

pushdwordptrcount ;壓入數(shù)據(jù)個數(shù)

pushoffsetarray ;壓數(shù)組的偏移地址

callmean ;調用求平均值子程序

;出口參數(shù):EAX=平均值(整數(shù))

addesp,8 ;平衡堆棧(壓入了8個字節(jié)數(shù)據(jù))

calldispsid ;顯示堆棧傳遞參數(shù)39〔例5-7〕計算有符號數(shù)平均值程序-2

;計算32位有符號數(shù)平均值子程序mean proc ;入口參數(shù):順序壓入數(shù)據(jù)個數(shù)和數(shù)組偏移地址

pushebp ;出口參數(shù):EAX=平均值

mov

ebp,esp

pushebx ;保護寄存器

pushecx pushedx

movebx,[ebp+8] ;EBX=取出的偏移地址

movecx,[ebp+12]

;ECX=取出的數(shù)據(jù)個數(shù)

xor

eax,eax ;EAX保存和值

xor

edx,edx ;EDX=指向數(shù)組元素堆棧傳遞參數(shù)40〔例5-7〕計算有符號數(shù)平均值程序-3mean1: addeax,[ebx+edx*4] ;求和

addedx,1 ;指向下一個數(shù)據(jù)

cmp

edx,ecx ;比較個數(shù)

jbmean1 ;循環(huán)

cdq ;將累加和EAX符號擴展到EDX

idiv

ecx ;有符號數(shù)除法,EAX=平均值

popedx ;恢復寄存器

popecx popebx

popebp

retmean endp求和溢出與個數(shù)為0的問題?示意圖41利用堆棧傳遞參數(shù)返回425.3多模塊程序結構程序分段、子程序等實現(xiàn)了程序模塊化開發(fā)大型應用程序時常使用多個源程序文件、目標代碼模塊等組成完整的程序MASM具體支持的方法源文件包含模塊連接子程序庫庫文件包含435.3.1源文件包含大型源程序可以合理地分放在若干個文本文件中各種常量定義、聲明語句等組織在包含文件(*.INC)常用的或有價值的宏定義存放在宏定義文件(*.MAC)常用的子程序形成匯編語言源文件(*.ASM)任何文本文件使用源文件包含偽指令INCLUDE將指定的文本文件內容插入主體源程序文件

INCLUDE文件名利用INCLUDE偽指令包含其他文件,其實質仍然是一個源程序,只不過是分在了幾個文件書寫子程序庫文件名要符合操作系統(tǒng)規(guī)范44〔例5-8〕存儲器數(shù)據(jù)顯示程序-1;文件名:eg0508.inc,例5-8程序的數(shù)據(jù)段內容

.data ;數(shù)據(jù)段dvar

dd1234abcdhinmsg db'EnterMemoryAddress:',0outmsg1 db'MemoryDataInHexDecimal:',0outmsg1 db'MemoryDataInSignedDecimal:',0temp dd0 ;共享變量writebuf db12dup(0) ;十進制輸出的顯示緩沖區(qū)包含文件45〔例5-8〕存儲器數(shù)據(jù)顯示程序-2;文件名:eg0508.asm,例5-8主程序

includeio32.inc ;源文件包含:32位I/O文件

includeeg0508.inc ;源文件包含:數(shù)據(jù)段文件

.code ;代碼段,主程序start: mov

dwordptr[temp],offset

dvar calldphd ;十六進制輸出,顯示變量DVAR地址以便輸入

calldispcrlf

mov

eax,offset

inmsg calldispmsg

callrdhd ;輸入存儲器地址,EAX返回

calldispcrlf主程序文件46〔例5-8〕存儲器數(shù)據(jù)顯示程序-3

mov

ebx,[eax] ;EBX=存儲器數(shù)據(jù)

mov

eax,offsetoutmsg1 calldispmsg

mov[temp],ebx ;共享變量傳遞參數(shù)

calldphd ;十六進制輸出

calldispcrlf

mov

eax,offsetoutmsg2 calldispmsg

mov

eax,ebx ;寄存器傳遞參數(shù)

callwrite ;十進制輸出

exit0 ;主程序結束,退出

includeeg0508s.asm ;源文件包含:子程序文件

endstart主程序文件47〔例5-8〕存儲器數(shù)據(jù)顯示程序-4;文件名:eg0508s.asm,例5-8程序的子程序rdhd proc ;十六進制輸入子程序

pushebx ;出口參數(shù):EAX=輸入的數(shù)據(jù)

pushecxrdhd1: xor

ebx,ebx ;EBX用于存放十六進制結果

movecx,8 ;限制輸入字符的個數(shù)rdhd2: callreadc ;輸入一個字符

cmpal,'0' ;檢測鍵入字符是否合法

jb

rderr ;不合法則返回重新輸入

cmpal,'9'

jberdhd4 ;輸入數(shù)碼:0~9,減30H子程序文件48〔例5-8〕存儲器數(shù)據(jù)顯示程序-5

cmp

al,'A'

jb

rderr

cmp

al,'F'

jberdhd3 ;輸入大寫字母:A~F,減7后、再減30H

cmp

al,'a'

jb

rderr

cmp

al,'f' ;輸入小寫字母:a~f,減20H、減7后、再減30H

ja

rderr subal,20h ;減20Hrdhd3: subal,7 ;減7rdhd4: subal,30h ;減30H 子程序文件49〔例5-8〕存儲器數(shù)據(jù)顯示程序-6

shlebx,4 ;EBX左移4位對應十六進制一位

orbl,al ;BL和AL相加

looprdhd2 ;循環(huán)鍵入字符

mov

eax,ebx ;通過EAX返回結果

popecx popebx retrderr: mov

eax,offset

errmsg calldispmsg

jmprdhd1errmsg db0dh,0ah,'Inputerror,enteragain:',0rdhd

endp子程序文件示意圖50例5-8程序的運行示例返回515.3.2模塊連接子程序單獨編寫,匯編形成目標模塊OBJ文件連接時輸入子程序模塊文件名用共用偽指令PUBLIC和外部偽指令EXTERN聲明PUBLIC標識符[,標識符…]

;定義標識符的模塊使用EXTERN標識符:類型[,標識符:類型…]

;調用標識符的模塊使用子程序在代碼段,與主程序文件采用相同的存儲模型,沒有開始執(zhí)行和結束執(zhí)行點處理好子程序與主程序之間的參數(shù)傳問題52〔例5-8〕存儲器數(shù)據(jù)顯示程序-7;文件名:eg0508es.asm,例5-8程序的子程序

includeio32.inc

publicrdhd,dphd,write ;子程序共用

externtemp:dword ;外部變量

.data ;數(shù)據(jù)段writebuf db12dup(0) ;顯示緩沖區(qū)

.code ;代碼段,子程序rdhd proc

c ;十六進制輸入子程序 … ;略,同EG0508S.ASM文件

end ;匯編結束子程序文件53〔例5-8〕存儲器數(shù)據(jù)顯示程序-8;文件名:eg0508e.asm,例5-8主程序 includeio32.inc

…… ;數(shù)據(jù)段

externrdhd:near,dphd:near,write:near

;外部子程序

publictemp ;變量共用

.code ;代碼段

……主程序文件ML/c/coffeg0508e.asmML/c/coffeg0508es.asmLINK32/subsystem:consoleeg0508e.objeg0508es.obj/libpath:bin操作過程545.3.3子程序庫子程序庫:統(tǒng)一管理子程序模塊遵循更加嚴格的子程序模塊要求子程序文件編寫完成、匯編形成目標模塊利用庫管理工具程序LIB.EXE:把子程序模塊逐個加入到子程序庫(.LIB) 使用子程序庫:在連接主程序模塊時提供子程序庫文件名LIB32/OUT:eg0508.libeg0508es.objLINK32/subsystem:consoleeg0508e.objeg0508.lib/libpath:bin操作過程55庫文件包含直接在源文件中用庫文件包含偽指令INCLUDELIB說明不用在連接時輸入庫文件名

INCLUDELIB文件名;declareprocedures

externreadc:near,readmsg:near externdispc:near,dispmsg:near,dispcrlf:near ...;declareI/Olibraries

includelibio32.libIO32.INC565.4宏結構本書統(tǒng)稱的宏結構宏匯編重復匯編條件匯編用于簡化源程序結構子程序等多模塊結構用于簡化目標代碼575.4.1宏匯編宏(Macro):具有宏名的一段匯編語句序列宏需要先定義宏名 MACRO形參表

…… ;宏定義體

ENDM然后程序中進行宏調用宏名實體參數(shù)在匯編時,宏指令被匯編程序用宏定義的代碼序列替代,實現(xiàn)宏展開581.宏定義和宏調用宏定義WriteString macromsg

pusheax leaeax,msg calldispmsg popeax

endm宏展開

pusheax leaeax,msg calldispmsg popeax宏調用

WriteString

msg59OF1131

12SF7ZF6AF40PF2CF0〔例5-9〕狀態(tài)標志顯示程序-1 ;宏定義rfbit macrobit1,bit2

xor

ebx,ebx ;EBX清0,用于保存字符

roleax,bit1 ;將某個標志左移BIT1位,進入當前CF

adcebx,30h ;轉換為ASCII字符

mov[rfmsg+bit2],bl ;保存于字符串BIT2位置

endm ;數(shù)據(jù)段rfmsg db'OF=0,SF=0,ZF=0,AF=0,PF=0,CF=0',13,10,060OF1131

12SF7ZF6AF40PF2CF0〔例5-9〕狀態(tài)標志顯示程序-2 ;代碼段

moveax,50 subeax,80 ;假設一個運算

pushfd ;將標志位寄存器的內容壓入堆棧

popeax ;將標志位寄存器的內容存入EAX

rfbit21,3 ;顯示OF(原來的OF需左移21位,進入當前CF)

rfbit4,9 ;顯示SF(原來的SF再左移4位,進入當前CF) ……61OF1131

12SF7ZF6AF40PF2CF0〔例5-9〕狀態(tài)標志顯示程序-3

rfbit21,3 ;顯示OF(原來的OF需左移21位,進入當前CF)1 xor

ebx,ebx ;EBX清0,用于保存字符1 roleax,21 ;將某個標志左移BIT1位,進入當前CF1 adcebx,30h ;轉換為ASCII字符1 mov[rfmsg+3],bl ;保存于字符串BIT2位置622.宏的參數(shù)和宏的操作符(1)宏定義asciiz macrostring db'&string&',0

endm宏展開

db’Thisisaexample.’,0宏調用

asciiz<Thisisaexample.>傳遞操作符替換操作符632.宏的參數(shù)和宏的操作符(2)宏定義asciiz macrostring db'&string&',0

endm宏展開

db’0<Number<10’,0宏調用

asciiz<0!<Number!<10>轉義操作符642.宏的參數(shù)和宏的操作符(3)宏定義asciiz macrostring db'&string&',0

endm宏展開

db’1023’,0宏調用

asciiz%(1024-1)表達式操作符653.宏的偽指令局部偽指令

LOCAL標號列表

;宏定義體采用了標號,應使用LOCAL加以說明

;它必須是宏定義MACRO語句之后的第一條語句刪除宏定義偽指令

PURGE宏名表

;不需要某個宏定義時,可以把它刪除宏定義退出偽指令

EXITM

;表示結束當前宏調用的展開66局部偽指令宏定義absol macrooprd

localnext

cmpoprd,0

jgenext

neg

oprdnext:

endm

;;這個偽指令要獨占一行宏調用和宏展開

absolwordptr[ebx]

cmpwordptr[ebx],0

jge

??0000

negwordptr[ebx]??0000:67〔例5-10〕通用寄存器顯示程序-1dreg32 macroreg32

localdreg1,dreg2

moveax,reg32 ;;顯示reg32寄存器

movecx,8

xor

ebx,ebxdreg1:

roleax,4

mov

edx,eax anddl,0fh adddl,30h

;;轉化為相應的ASCII碼值

cmpdl,39h

;;區(qū)別0~9和A~F數(shù)碼

jbe

dreg2 adddl,768〔例5-10〕通用寄存器顯示程序-2dreg2:

movrd®32&[ebx+4],dl ;;存于對應的字符串

incebx

cmp

ebx,ecx

jb

dreg1

endm ;數(shù)據(jù)段rdeax db'EAX=00000000,'

……

;代碼段,顯示EAX dreg32eax

……

694.宏與子程序僅是源程序級的簡化:宏調用在匯編時進行程序語句的展開,不需要返回;不減小目標程序,執(zhí)行速度沒有改變通過形參、實參結合實現(xiàn)參數(shù)傳遞,簡捷直觀、靈活多變當程序段較短或要求較快執(zhí)行時,應選用宏還是目標程序級的簡化:子程序調用在執(zhí)行時由CALL指令轉向、RET指令返回;形成的目標代碼較短,執(zhí)行速度減慢需要利用寄存器、存儲單元或堆棧等傳遞參數(shù)當程序段較長或為減小目標代碼時,要選用子程序705.4.2重復匯編重復匯編指在匯編過程中,重復展開一段相同或基本相同的語句重復匯編沒有名字,不能被調用重復匯編常用在宏定義體中,也可以在一般匯編語句中使用重復匯編偽指令有3個:REPEAT ;按參數(shù)值重復FOR ;按參數(shù)個數(shù)重復FORC ;按參數(shù)的字符個數(shù)重復最后,用ENDM結束711.按參數(shù)值重復偽指令REPEATREPEAT重復次數(shù)

……

;重復體ENDMchar=20hdbcharrepeat95-1char=char+1dbcharendmdbchar ;等效于db20hchar=char+1dbchar ;等效于db21h ...char=char+1dbchar ;等效于db7eh722.按參數(shù)個數(shù)重復偽指令FORFOR形參,〈實參表〉

……

;重復體ENDMforregad,<eax,ebx,ecx,edx>

pushregadendmpusheaxpushebxpushecxpushedx733.按參數(shù)字符個數(shù)重復偽指令FORCFORC

形參,字符串

……

;重復體ENDMforcregad,dcbapope®ad&xendmpopedxpopecxpopebxpopeax745.4.3條件匯編根據(jù)某種條件確定是否匯編某段語句序列它與高級語言的條件編譯命令類似條件匯編偽指令的一般格式:

IFxx

表達式

;條件滿足,匯編分支語句體1

分支語句體1 [ELSE ;條件不滿足,匯編分支語句體2

分支語句體2]

ENDIF ;條件匯編結束751.IF/IFE偽指令pdata macronum

ifnumlt100 ;如果num<100,匯編如下語句dbnumdup(?)

else ;否則,匯編如下語句db100dup(?)

endif

endmpdata12 ;宏調用①db12dup(?) ;宏匯編結果①----------------------------pdata102 ;宏調用②db100dup(?) ;宏匯編結果②762.IFDEF/IFNDEF偽指令ifdef

RealMode ;當定義有RealMode符號時,匯編如下語句

mov

ax,@data

mov

ds,axendifRealMode=1 ;定義RealMode符號773.IFB/IFNB偽指令maxnum macrodvar1:req,dvar2,dvar3 localmaxnum1,maxnum2

moveax,dvar1

ifnb<dvar2>

;當有DVAR2實參時,匯編如下語句

cmpeax,dvar2

jgemaxnum1

moveax,dvar2

endifmaxnum1: ……

endm

maxnum3,5 ;宏調用

moveax,3

cmpeax,5

jge??0002

moveax,5??0002:784.IFIDN/IFDIF和IFIDNI/IFDIFI偽指令print macroformat,var

mov

al,var

ifidni<format>,<b> calldispbb

;二進制顯示用格式符“b”

exitm

;不再進行宏展開

endif

……

endmprint

b,var;二進制形式顯示:01100100第5章習題:模塊化程序設計5.1簡答題(1、4、5、6、7)5.2

判斷題(2、5、6、7、8)5.3

填空題(1、4、5、6、7)5.7、5.8、5.11、5.13第6章Windows編程6.1操作系統(tǒng)函數(shù)調用6.2控制臺應用程序6.3圖形窗口應用程序第6章Windows編程熟悉匯編語言調用API函數(shù)的方法掌握控制臺輸入輸出函數(shù)熟悉MASM的高級特性理解Windows圖形窗口程序的編寫826.1

操作系統(tǒng)函數(shù)調用操作系統(tǒng)以其提供的系統(tǒng)函數(shù)(系統(tǒng)功能Systemfunction)支持程序員進行編程Windows的系統(tǒng)函數(shù)(功能)以動態(tài)連接庫DLL(Dynamic-LinkLibrary)形式提供,利用其應用程序接口API(ApplicationProgramInterface)調用DDL庫中的函數(shù)API是一些類型、常量和函數(shù)的集合,提供了編程中使用庫函數(shù)的途徑Win16:16位Windows的APIWin32:32位Windows的API836.1.1

動態(tài)連接庫靜態(tài)連接:連接程序從庫文件中抽取需要的子程序插入到最終的可執(zhí)行代碼中動態(tài)連接:程序運行時才將代碼加載到主存動態(tài)連接庫:保存程序運行時需要重復使用的代碼的文件3個最重要的Windows動態(tài)連接庫KERNEL32.DLL:主要處理內存管理和進程調度USER32.DLL:主要控制用戶界面GDI32.DLL:負責圖形方面的操作導入庫(ImportLibrary):程序開發(fā)的連接階段使用,與一個動態(tài)連接庫DLL對應846.1.2MASM的過程聲明和調用過程聲明偽指令PROTO: 事先聲明過程的結構 (包括操作系統(tǒng)API函數(shù)、高級語言的函數(shù))

過程名 PROTO [調用距離][語言類型]

[,[參數(shù)]∶類型]...過程調用偽指令INVOKE

實現(xiàn)過程調用

INVOKE 過程名[,參數(shù),...]856.1.3

程序退出函數(shù)Win32程序員參考手冊VOIDExitProcess(UINTuExitCode //exitcodeforallthreads);匯編語言聲明ExitProcess

PROTO,:DWORD匯編語言調用invoke

ExitProcess,0將函數(shù)調用定義成宏exit MACROdwexitcode

invokeExitProcess,dwexitcode

ENDM宏調用exit 0866.2

控制臺應用程序Windows應用程序開始運行創(chuàng)建控制臺(Console)窗口或創(chuàng)建圖形界面窗口32位Windows控制臺程序像增強版的MS-DOS程序使用標準控制臺

標準輸入設備(鍵盤)

標準輸出設備(顯示器)32位控制臺程序運行在保護方式通過API使用Windows的動態(tài)鏈接庫函數(shù)876.2.1控制臺輸出編寫控制臺程序需要調用控制臺函數(shù),實現(xiàn)控制臺(顯示器)輸出控制臺(鍵盤)輸入幾乎所有的控制臺函數(shù)都要求將控制臺句柄作為第一個參數(shù)傳遞給它們本節(jié)介紹的控制臺函數(shù)存在于KERNEL32.DLL動態(tài)庫中程序開發(fā)需要使用KERNEL32.LIB導入庫文件881.

控制臺句柄句柄(Handle)是一個32位無符號整數(shù)用來唯一確定一個對象例如某個輸入設備、輸出設備或者一個圖形標準輸入句柄

STD_INPUT_HANDLE

equ-10標準輸出句柄

STD_OUTPUT_HANDLE

equ-11標準錯誤句柄

STD_ERROR_HANDLE

equ-12GetStdHandle函數(shù)獲取控制臺輸入或輸出的句柄實例用于控制臺程序的輸入輸出操作892.

控制臺輸出函數(shù)顯示器輸出API函數(shù)WriteConsole將一個字符串輸出到屏幕上支持標準的ASCII控制字符,例如回車、換行等Win32API中可以使用兩種字符集8位ASCII字符集,函數(shù)名以字母A結尾16位Unicode字符集,函數(shù)名以字母W結尾WriteConsole參數(shù)第一個:控制臺輸出句柄實例第二個:指向字符串的指針、即緩沖區(qū)地址第三個:指明字符串長度,是一個32位整數(shù)第四個:指向一個整數(shù)變量,返回實際輸出的字符數(shù)第五個:保留,設置為090〔例6-1〕控制臺輸出程序-1

.686 .modelflat,stdcall optioncasemap:none

includelib

bin\kernel32.libExitProcess

proto,:dwordGetStdHandle proto,:dwordWriteConsoleA proto,:dword,:dword,:dword,:dword,:dwordWriteConsole equ<WriteConsoleA>STD_OUTPUT_HANDLEequ-11 .datamsg db'Hello,Assembly!',13,10count equ$-msgoutsize dd091〔例6-1〕控制臺輸出程序-2 .codestart:

;獲得輸出句柄 invokeGetStdHandle,STD_OUTPUT_HANDLE

;顯示信息 invokeWriteConsole,eax,offsetmsg,count,offsetoutsize,0

;退出 invokeExitProcess,0 endstartHello,Assembly!運行結果926.2.2

控制臺輸入鍵盤輸入API函數(shù)ReadConsole將鍵盤輸入的文本保存到一個緩沖區(qū)第一個:控制臺輸入句柄實例第二個:輸入緩沖區(qū)指針第三個:要讀取字符的最大數(shù)量第四個:實際輸入字符數(shù)量的指針第五個:未使用,設置為0調用ReadConsole函數(shù)時系統(tǒng)等待用戶輸入、并回車確認(例如用戶輸入了3個字符,依次是123)第4個參數(shù)的變量保存用戶輸入字符個數(shù)再加2的結果(例如本例是5)(內容用十六進制數(shù)表達依次是3132330D0A)定義輸入緩沖區(qū)要多留兩個字節(jié)93〔例6-2〕信息輸入輸出程序-1

.686 .modelflat,stdcall optioncasemap:none

includelib

bin\kernel32.libExitProcess

proto,:dwordexit MACROdwexitcode invokeExitProcess,dwexitcode ENDMGetStdHandle

proto,:dwordWriteConsoleA

proto,:dword,:dword,:dword,:dword,:dwordWriteConsole

equ<WriteConsoleA>94〔例6-2〕信息輸入輸出程序-2ReadConsoleA proto,:dword,:dword,:dword,:dword,:dwordReadConsole equ<ReadConsoleA>STD_INPUT_HANDLEequ-10STD_OUTPUT_HANDLEequ-11 .datamsg1 db'Pleaseenteryourname:',0msg2 db'Welcome',0nbuf db80dup(0)msg3 db'toWin32Console!',0

;設置輸入緩沖區(qū)最大255個字符95〔例6-2〕信息輸入輸出程序-3

.codestart:

mov

eax,offsetmsg1 ;提示輸入

calldispmsg

mov

eax,offset

nbuf

;輸入信息

callreadmsg

mov

eax,offsetmsg2

calldispmsg

mov

eax,offset

nbuf

;顯示輸入信息

calldispmsg

mov

eax,offsetmsg3

calldispmsg

exit096〔例6-2〕信息輸入輸出程序-4 .data_outsize dd0_outhandle dd0dispmsg proc

;字符串顯示子程序

pusheax

;入口參數(shù):EAX=字符串地址

pushebx pushecx pushedx pusheax

;保存入口參數(shù),即字符串地址

invokeGetStdHandle,STD_OUTPUT_HANDLE

mov[_outhandle],eax

popebx

;EBX=字符串地址

xor

ecx,ecx

;計算字符串長度97〔例6-2〕信息輸入輸出程序-5dispm1: moval,[ebx+ecx] testal,al jzdispm2 incecx jmpdispm1dispm2:

invokeWriteConsole,[_outhandle],ebx,ecx,offset_outsize,0

popedx popecx popebx popeax retdispmsg

endp98〔例6-2〕信息輸入輸出程序-6 .data_insize dd0_inbuffer db255dup(0)readmsg proc ;字符串輸入子程序

pushebx ;入口參數(shù):EAX=緩沖區(qū)地址

pushecx pushedx pusheax

;保護輸入的緩沖區(qū)地址參數(shù)

invokeGetStdHandle,STD_INPUT_HANDLE invokeReadConsole,eax,offset_inbuffer,255,offset_insize,0

subdwordptr[_insize],2

xor

ecx,ecx popebx

;獲得緩沖區(qū)地址99〔例6-2〕信息輸入輸出程序-7readm1: moval,_inbuffer[ecx] mov[ebx+ecx],al ;將輸入的字符串復制到用戶緩沖區(qū)

incecx cmpecx,[_insize] jbreadm1

movbyteptr[ebx+ecx],0

;最后填入結尾字符0

mov

eax,ecx popedx popecx popebx retreadmsg

endpPleaseenteryourname:JerryWelcomeJerrytoWin32Console!運行結果1006.2.3單字符輸入默認模式下ReadConsole函數(shù)實現(xiàn)一行字符輸入最后必須用回車鍵結束設置為單字符輸入模式后ReadConsole函數(shù)實現(xiàn)一個字符輸入自動結束調用需要修改輸入模式獲取控制臺模式函數(shù)GetConsoleMode設置控制臺模式函數(shù)SetConsoleMode101〔例6-3〕單字符輸入程序-1 …GetConsoleModeproto,:dword,:dwordSetConsoleModeproto,:dword,:dword .datamsg db'Pressanykeytoend'count equ$-msgoutsize dd0inhandle dd0savemode dd0 ;保存控制臺模式insize dd0inbuffer db255dup(0) ;設置輸入緩沖區(qū)最大255個字符102〔例6-3〕單字符輸入程序-2

.codestart: invokeGetStdHandle,STD_OUTPUT_HANDLE

;提示按任意鍵

invokeWriteConsole,eax,offsetmsg,count,offsetoutsize,0 invokeGetStdHandle,STD_INPUT_HANDLE mov[inhandle],eax

invokeGetConsoleMode,[inhandle],offsetsavemode

;獲得控制臺模式

invokeSetConsoleMode,[inhandle],0

;設置為單字符輸入模式103〔例6-3〕單字符輸入程序-3

invokeReadConsole,[inhandle],offsetinbuffer,1,offsetinsize,0

;輸入字符

invokeSetConsoleMode,[inhandle],[savemode]

;恢復原控制臺模式

invokeExitProcess,0 ;退出Pressanykeytoend運行結果1046.3

圖形窗口應用程序Windows圖形界面以窗口、對話框、菜單、按鈕等實現(xiàn)用戶交互用匯編語言編寫圖形窗口應用程序就是調用這些API函數(shù)1056.3.1

消息窗口消息窗口是常見的Windows圖形窗口顯示形式使用MessageBox函數(shù)Win32程序員參考手冊的定義int

MessageBox(HWNDhWnd,LPCTSTRlpText,LPCTSTRlpCaption,UINTuType);hWnd:父窗口的句柄lpText:要顯示字符串的地址指針,字符串的首地址lpCaption:消息窗標題的地址指針uType:指明該消息窗的類型106〔例6-4〕消息窗口程序-1

.686 .modelflat,stdcall optioncasemap:none

includelib

bin\kernel32.lib

includelib

bin\user32.libExitProcess

proto,:dwordMessageBoxA

PROTO,:dword,:dword,:dword,:dwordMessageBox

equ<MessageBoxA>NULL equ0MB_OK equ0 .dataszCaption db‘歡迎',0outbuffer db‘你好,匯編語言!',0107〔例6-4〕消息窗口程序-2 .codestart:

invoke

MessageBox,NULL,offsetoutbuffer,offset

szCaption,MB_OK invokeExitProcess,NULL endstart連接時應該使用參數(shù)/subsystem:windows1086.3.2結構變量結構類型的說明 結構名STRUCT …… ;數(shù)據(jù)定義語句 結構名ENDS結構變量的定義 變量名結構名<字段初值表>結構變量及其字段的引用引用結構變量,只要直接書寫結構變量名引用其中某個字段,采用圓點“.”操作符結構變量名.結構字段名109〔例6-5〕系統(tǒng)時鐘顯示程序-1

;系統(tǒng)時間的結構類型說明SYSTEMTIME

struct

wYear dw0 ;年(4位數(shù))

wMonth dw0 ;月(1~12)wDayOfWeek dw0 ;星期(0~6,0=星期日,……)wDay dw0 ;日(1~31)

wHour dw0 ;時(0~23)

wMinute dw0 ;分(0~59)

wSecond dw0

;秒(0~59)

wMillisconds dw0 ;毫秒(0~999)SYSTEMTIME ends

;函數(shù)聲明,參數(shù)是指向結構變量的指針GetLocalTime proto,:dword110〔例6-5〕系統(tǒng)時鐘顯示程序-2 .datamytime SYSTEMTIME<> ;系統(tǒng)時間的結構變量定義timestring db'--:--:--',0timecaption db'當前時間',0 .codestart: invokeGetLocalTime,offsetmytime ;獲得當前時間

movebx,offsettimestring ;EBX指向“時”的保存位置

writedec

[mytime.wHour]

;轉換為ASCII字符

invokeMessageBox,0,offsettimestring,offsettimecaption,1writedec111宏:writedecwritedec macrotime ;;將二進制數(shù)轉換為2位十進制數(shù)

;;再轉為ASCII字符保存

movax,time movcl,10 divcl ;;商AL是百位,余數(shù)AH是個位

addax,3030h ;;轉換為ASCII

mov[ebx],ax ;;對應顯示順序,百位先顯示保存在低地址

endm返回1126.3.3MASM的高級語言特性MASM6.0引入高級語言的程序設計特性擴展的過程定義PROC過程聲明和過程調用偽指令PROTOINVOKE條件控制偽指令.IF.ELSE.ENDIF循環(huán)控制偽指令.WHILE.ENDW.REPEAT.UNTIL要調用帶參數(shù)過程定義的過程,不應采用CALL指令,因為比較煩瑣應該采用過程調用偽指令INVOKE使用INVOKE偽指令的前提是需要用PROTO偽指令對過程進行聲明過程名 PROC

調用距離語言類型作用范圍<起始參數(shù)> USES寄存器列表,參數(shù):類型

LOCAL參數(shù)表

… ;匯編語言語句過程名 ENDP過程聲明偽指令:事先聲明過程的結構過程名 PROTO調用距離語言類型,參數(shù):類型過程調用偽指令

INVOKE

過程名,參數(shù),...如何調用1.擴展的過程定義114〔例6-6〕使用擴展過程定義程序-1mean protoc,:dword,:dword

;過程聲明,使用C語言規(guī)范

.dataarray dd675,…,-67,4257count equ($-array)/4 .codestart: ;主程序:調用求平均值子程序,然后顯示

invokemean,offsetarray,count

calldispsid

;顯示 exit0 ;子程序:計算32位有符號數(shù)平均值 ;入口參數(shù):D表示數(shù)組地址、NUM表示元素個數(shù) ;出口參數(shù):EAX=平均值115〔例6-6〕使用擴展過程定義程序-2mean proccusesebxecxedx,d:dword,num:dword

movebx,d ;EBX=數(shù)組指針

movecx,num ;ECX=元素個數(shù)

xoreax,eax ;EAX保存和值

xoredx,edx ;EDX=指向數(shù)組元素mean1: addeax,[ebx+edx*4] ;求和

addedx,1 ;指向下一個數(shù)據(jù)

cmpedx,ecx ;比較個數(shù)

jbmean1 ;循環(huán)

cdq ;將累加和EAX符號擴展到EDX

idivecx ;有符號數(shù)除法,EAX=平均值

retmean endp用“/Sa”參數(shù)匯編,最大化源代碼列表116〔例6-6〕列表文件-1start:

;主程序:調用求平均值子程序,然后顯示

invokemean,offsetarray,count* push+00000000Ah* pushOFFSETarray* callmean* addesp,000000008h

calldispsid

;顯示

exit0* push+000000000h* callExitProcess1 invokeExitProcess,0117〔例6-6〕列表文件-2mean proccusesebxecxedx,d:dword,num:dword* pushebp* movebp,esp* pushebx* pushecx* pushedx …… ;這部分同源程序,省略

ret* popedx* popecx* popebx* leave

;movesp,ebp/popebp* ret00000hmean endpmovebx,dwordptr[ebp+8]movecx,dwordptr[ebp+0ch]1182.條件控制類似高級語言中IF、THEN、ELSE和ENDIF的相應功能在匯編時要展開,自動生成相應的比較和條件轉移指令序列,實現(xiàn)程序分支

.IF條件表達式

;條件為真(值為非0)

分支體

;執(zhí)行分支體[ .ELSEIF ;前面IF[以及前面ELSEIF]條件為假 ;并且當前ELSEIF條件為真

分支體

]

;執(zhí)行分支體[ .ELSE ;前面IF[以及前面ELSEIF]條件為假

分支體

]

;執(zhí)行分支體

.ENDIF ;分支結束條件119條件表達式中的操作符操作符功能操作符功能操作符功能==等于&&邏輯與CARRY?CF=1?!=不等于||邏輯或OVERFLOW?OF=1?>大于!邏輯非PARITY?PF=1?>=大于等于SIGN?SF=1?<小于&位測試ZERO?ZF=1?<=小于等于()改變優(yōu)先級返回〔例6-7〕使用條件控制的程序-1求EAX絕對值程序單分支結構

c

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論