



版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Linux 中的匯編語言在閱讀 Linux 源代碼時(shí),你可能碰到一些匯編語言片段,有些匯編語言出現(xiàn)在以.S為擴(kuò)展名的匯編文件中,在這種文件中,整個(gè)程序全部由匯編語言組成。有些匯編命令出現(xiàn)在以 .c 為擴(kuò)展名的C 文件中,在這種文件中,既有C 語言,也有匯編語言,我們把出現(xiàn)在 C代碼中的匯編語言叫所“嵌入式”匯編。不管這些匯編代碼出現(xiàn)在哪里,它在一定程度上都成為閱讀源代碼的攔路虎。盡管 C語言已經(jīng)成為編寫操作系統(tǒng)的主要語言,但是,在操作系統(tǒng)與硬件打交道的過程中,在需要頻繁調(diào)用的函數(shù)中以及某些特殊的場(chǎng)合中,C語言顯得力不從心,這時(shí),繁瑣但又高效的匯編語言必須粉墨登場(chǎng)。因此,在了解一些硬件的基礎(chǔ)上,
2、必須對(duì)相關(guān)的匯編語言知識(shí)也所有了解。讀者可能有過在DOS操作系統(tǒng)下編寫匯編程序的經(jīng)歷,也具備一定的匯編知識(shí)。但是,在 Linux 的源代碼中,你可能看到了與Intel的匯編語言格式不一樣的形式,這就是AT&T 的 386 匯編語言。一、 AT&T 與 Intel匯編語言的比較我們知道, Linux 是 Unix 家族的一員,盡管Linux 的歷史不長(zhǎng),但與其相關(guān)的很多事情都發(fā)源于Unix 。就 Linux 所使用的386 匯編語言而言,它也是起源于Unix 。Unix 最初是為 PDP 11開發(fā)的,曾先后被移植到VAX 及 68000 系列的處理器上,這些處理器上的匯編語言都采
3、用的是AT&T 的指令格式。當(dāng)Unix 被移植到i386 時(shí),自然也就采用了AT&T 的匯編語言格式,而不是Intel的格式。盡管這兩種匯編語言在語法上有一定的差異,但所基于的硬件知識(shí)是相同的,因此,如果你非常熟悉Intel的語法格式,那么你也可以很容易地把它“移植“到AT&T 來。下面我們通過對(duì)照Intel與 AT&T 的語法格式,以便于你把過去的知識(shí)能很快地“移植”過來。1前綴在 Intel的語法中,寄存器和和立即數(shù)都沒有前綴。但是在AT&T 中,寄存器前冠以“”,而立即數(shù)前冠以“$” 。在 Intel的語法中,十六進(jìn)制和二進(jìn)制立即數(shù)后綴分別冠以“
4、h” 和“ b” ,而在 AT&T 中,十六進(jìn)制立即數(shù)前冠以“0x ”,表 2.2 給出幾個(gè)相應(yīng)的例子。表 2.2 Intel 與 AT&T 前綴的區(qū)別Intel語法AT&T 語法moveax,8movl$8,%eaxmovebx,0ffffhmovl$0xffff,%ebxint80hint$0x802. 操作數(shù)的方向Intel與 AT&T 操作數(shù)的方向正好相反。在Intel語法中,第一個(gè)操作數(shù)是目的操作數(shù),第二個(gè)操作數(shù)源操作數(shù)。而在 AT&T 中,第一個(gè)數(shù)是源操作數(shù),第二個(gè)數(shù)是目的操作數(shù)。由此可以看出,AT&T 的語法符合人們通常的閱讀習(xí)慣。
5、例如:在Intel中,moveax,ecx在AT&T 中, movl(%ecx),%eax3內(nèi)存單元操作數(shù)從上面的例子可以看出,內(nèi)存操作數(shù)也有所不同。在Intel的語法中,基寄存器用“”括起來,而在AT&T 中,用“()”括起來。例如:在Intel中, moveax,ebx+5在AT&T, movl5(%ebx),%eax4間接尋址方式與Intel的語法比較,AT&T 間接尋址方式可能更晦澀難懂一些。Intel的指令格式是segreg:base+index*scale+disp,而 AT&T 的格式是%segreg:disp(base,index,sca
6、le)。其中index/scale/disp/segreg全部是可選的,完全可以簡(jiǎn)化掉 。如果沒有指定 scale 而指定了index ,則 scale 的缺省值 為 1。segreg 段寄存器 依賴 于指令以及應(yīng)用程序是運(yùn)行在實(shí)模式還是保護(hù)模 式下,在 實(shí)模 式下,它 依賴 于指令,而在保護(hù)模 式下, segreg是多 余的。在AT&T 中,當(dāng)立即數(shù)用在 scale/disp 中時(shí),不應(yīng)當(dāng)在其前冠以“$” 前綴,表2.3 給出其語法及幾個(gè)相應(yīng)的例子。表 2.3內(nèi)存操作數(shù)的語法及舉例Intel 語法AT&T 語法指令foo,segreg:base+index*scale+dis
7、p指令%segreg:disp(base,index,scale),foomoveax,ebx+20hMovl0x20(%ebx),%eaxaddeax,ebx+ecx*2hAddl(%ebx,%ecx,0x2),%eaxleaeax,ebx+ecxLeal(%ebx,%ecx),%eaxsubeax,ebx+ecx*4h-20hSubl-0x20(%ebx,%ecx,0x4),%eax從表中可以看出,AT&T 的語法比較晦澀難懂,因?yàn)閎ase+index*scale+disp一眼就可以看出其 含義 ,而 disp(base,index,scale)則不可能 做到這 點(diǎn)。這種尋址方式常
8、常用在訪問 數(shù)據(jù)結(jié)構(gòu) 數(shù)組中某個(gè)特定元素內(nèi)的一個(gè)字段,其中,base 為數(shù)組的起始地址, scale 為 每個(gè)數(shù)組元 素的大小 , index 為下 標(biāo)。如果數(shù)組元素還是一個(gè) 結(jié)構(gòu) ,則 disp 為具 體字 段在 結(jié)構(gòu) 中的 位移。5操作碼的后綴在上面的例子中你可能已注意 到,在AT&T 的操作碼后面有一個(gè)后綴,其含義 就是指出操作碼的大小 。“ l ”表 示長(zhǎng)整數(shù)( 32 位),“ w” 表示字 ( 16位),“ b” 表示字節(jié)( 8 位)。而在 Intel的語法中,則要在內(nèi)存單元操作數(shù)的前面加上 byte ptr、 word ptr,和 dword ptr ,“ dword ”對(duì)
9、應(yīng)“ long ”。表 2.4 給出幾個(gè)相應(yīng)的例子。表 2.4 操作碼的后綴 舉例Intel 語法AT&T 語法Moval,blmovb%bl,%alMovax,bxmovw%bx,%axMoveax,ebxmovl%ebx,%eaxMoveax, dword ptr ebxmovl(%ebx),%eax二、AT&T 匯編語言的相關(guān)知識(shí)在 Linux 源代碼中,以.S 為擴(kuò)展名的文件是“純 ”匯編語言的文件。這里,我們結(jié)合具體的例子 再介紹 一些 AT&T 匯編語言的相關(guān)知識(shí)。1 GNU匯編程序GAS( GNU Assembly 和連接程序當(dāng)你編寫了一個(gè)程序后,就需要對(duì)
10、其進(jìn)行匯編( assembly )和 連接。在 Linux 下有兩種方式,一種是使用匯編程序GAS和連接程序 ld ,一種是使用gcc 。我們先來看一下GAS和 ld:GAS把匯編語言源文件(.o) 轉(zhuǎn)換 為目 標(biāo)文件( .o),其基 本語法如下:as filename.s -o filename.o一旦創(chuàng)建 了一個(gè)目 標(biāo)文件,就需要把它連接并執(zhí)行 ,連接一個(gè)目 標(biāo)文件的基 本語法為:ld filename.o -o filename這里filename.o是目 標(biāo)文件名,而filename是輸出 (可執(zhí)行 ) 文件。GAS使用的是AT&T 的語法而不是Intel的語法,這就再次說明
11、了 AT&T 語法是Unix世界 的標(biāo)準(zhǔn) ,你必須熟悉它。如果要使用GNC的 C編譯器 gcc ,就可以一 步完成匯編和連接,例如:gcc -o example example.S這里, example.S 是你的匯編程序,輸出文件(可執(zhí)行 文件)名為example 。其中,擴(kuò)展名必須為大寫的 S,這是因?yàn)?,令?像 #include 、#define 、#ifdef匯編程序中使用C的預(yù)處理命令。大寫的 S可以使 gcc 自動(dòng)識(shí)別匯編程序中的C預(yù)處理命、 #endif等,也就是 說,使用 gcc 進(jìn)行編譯,你可以在2. AT&T 中的 節(jié)( Section )在 AT&
12、T 的語法中,一個(gè)節(jié)由 .section關(guān)鍵詞 來 標(biāo)識(shí),當(dāng)你編寫匯編語言程序時(shí),至少需要有以下 三種節(jié):.section .data:這種 節(jié)包含 程序已初 始化 的數(shù) 據(jù),也就是說, 包含 具有初 值的那些 變量,例如:hello: .string "Hello world!n"hello_len : .long 13.section .bss:這個(gè) 節(jié)包含 程序 還未 初始化 的數(shù) 據(jù) ,也就是 說, 包含 沒有初 值的那些 變量。當(dāng)操作系統(tǒng)裝入這個(gè)程序時(shí)將把這些 變量 都置為 0,例如:name: .fill 30#用來 請(qǐng)求 用戶輸 入名 字name_len :
13、.long 0#名字的長(zhǎng)度(尚未 定義 )當(dāng)這個(gè)程序被裝入時(shí), name 和name_len 都被 置為 0。如果你在.bss 節(jié)不小心給一個(gè)變量賦 了初值,這個(gè) 值也會(huì)丟失 ,并且變量 的值仍為 0。使用 .bss 比使用 .data 的優(yōu)勢(shì) 在于, .bss 節(jié)不占用磁盤 的空間。在磁盤 上,一個(gè)長(zhǎng)整數(shù)就足以存 放 .bss 節(jié) 。當(dāng)程序被 裝入到內(nèi)存時(shí),操作系統(tǒng)也只分 配給這個(gè) 節(jié) 4 個(gè)字節(jié) 的內(nèi)存大小 。注意 :編 譯程序把 .data 和 .bss 在 4 字節(jié) 上對(duì) 齊( align ),例如, .data 總共 有 34 字節(jié),那么編 譯程序把它對(duì)其在36 字節(jié) 上,也就是說,
14、實(shí)際 給它 36 字節(jié) 的 空間。.section .text:這個(gè) 節(jié)包含 程序的代碼,它是只讀節(jié),而 .data和 .bss 是讀 寫節(jié)。3匯編程序指令(Assembler Directive)上面介紹 的 .section 就是匯編程序指令的一種,GNU匯編程序 提供 了很多這樣的指令( directiv),這種指令都是以句點(diǎn) ( .)為開 頭,后 跟指令名( 小寫字母 ),在此,我們只介紹 在內(nèi) 核源代碼中出現(xiàn)的幾個(gè)指令(以arch/i386/kernel/head.S中的代碼為例)。( 1) ascii "string".ascii表示零個(gè)或多個(gè)(用 逗號(hào)隔 開)
15、字符串,并把每個(gè)字符串(結(jié)尾不自動(dòng)加“ 0“ 字節(jié) )中的 字符放在連續(xù) 的地址單元。還有一個(gè)與 .ascii類似 的 .asciz , z 代表“ 0“ ,即 每個(gè)字符串結(jié)尾 自動(dòng)加 一個(gè)” 0“字節(jié) ,例如:int_msg:.asciz "Unknown interruptn"( 2) .byte 表達(dá)式.byte 表示零或 多個(gè)表 達(dá)式(用 逗號(hào)隔 開), 每個(gè)表 達(dá) 式被 放在下一個(gè) 字節(jié) 單元。( 3) .fill表達(dá)式形式: .fill repeat , size , value其中,repeatsize和valueFill的含義 是反 復(fù)拷貝size個(gè)字節(jié) 。
16、、都是常 量表達(dá)式。Repeat 可以 大于等于 0。size也可以 大于等于 0,但不能超過 8,如果 超過 8,也 只取 8。把repeat個(gè)字節(jié) 以 8 個(gè)為一組, 每組的最高4 個(gè)字節(jié) 內(nèi)容為 0,最 低 4 字節(jié) 內(nèi)容 置為 value 。Size 和 value 為可選 項(xiàng) 。如果第二個(gè)逗號(hào) 和 value 值不存在, 則假 定 value 為 0。如果第一個(gè) 逗號(hào) 和 size 不存在, 則假 定 size 為 1。例如,在 Linux 初始化 的過程中,對(duì)全局描述 符表 GDT進(jìn)行設(shè)置 的最后一 句為:.fill NR_CPUS*4,8,0/* space for TSS
17、9;s and LDT's */因?yàn)槊總€(gè)描述 符正好 占 8 個(gè)字節(jié) ,因此, .fill給每個(gè) CPU留有存 放 4 個(gè)描述 符的 位置。( 4) .globl symbol.globl使得 連接程序( ld )能 夠看到 symbl 。如果你的局部程序中定義了 symbl ,那么,與這個(gè) 局部程序 連接的其 他局 部程序也能存取 symbl ,例如:.globl SYMBOL_NAME(idt).globl SYMBOL_NAME(gdt)定義 idt和 gdt 為全 局 符號(hào)。( 5) quad bignums.quad 表示零 個(gè)或多個(gè) bignums (用 逗號(hào) 分隔),對(duì)于
18、 每個(gè) bignum ,其 缺省值 是 8 字節(jié)整數(shù)。如果bignum 超過 8 字節(jié) ,則打印 一個(gè) 警告信息;并只取bignum 最低 8 字節(jié) 。例如,對(duì)全 局描述 符表的 填充 就用到這個(gè)指令:.quad 0x00cf9a000000ffff/* 0x10 kernel 4GB code at 0x00000000 */.quad 0x00cf92000000ffff/* 0x18 kernel 4GB data at 0x00000000 */.quad 0x00cffa000000ffff/* 0x23 user4GB code at 0x00000000 */.quad 0x00
19、cff2000000ffff/* 0x2b user4GB data at 0x00000000 */( 6) rept count把.rept 指令與 .endr 指令 之間的 行重復(fù) count 次,例如.rept3.long0.endr相當(dāng)于.long0.long0.long0( 7) space size , fill這個(gè)指令 保留 size 個(gè)字節(jié) 的空間, 每個(gè)字節(jié) 的值為 fill。size和 fill都是常 量表達(dá)式。如果 逗號(hào) 和 fill被省略 ,則假 定 fill為 0,例如在arch/i386/bootl/setup.S中有一 句:.space 1024表示保留 102
20、4字節(jié)的空間,并且每 個(gè)字節(jié) 的值為 0。( 8) .word expressions這個(gè)表 達(dá)式表 示任意 一節(jié)中的一個(gè) 或多個(gè)表 達(dá)式(用 逗號(hào) 分開),表達(dá)式的 值占 兩個(gè)字節(jié) ,例如:gdt_descr:.word GDT_ENTRIES*8-1表示變量 gdt_descr 的置為 GDT_ENTRIES*8-1( 9) .long expressions這與.word 類似( 10) .org new-lc , fill把當(dāng)前節(jié)的位置計(jì) 數(shù)器 提前到 new-lc ( new location counter)。new-lc或者是一個(gè)常量表達(dá)式, 或者是一個(gè)與當(dāng)前子節(jié)處于同一 節(jié)的表
21、 達(dá) 式。也就是 說,你不能用 .org 橫跨節(jié):如果 new-lc是個(gè) 錯(cuò)誤 的值,則 .org 被忽略 。.org 只能增加位置計(jì) 數(shù)器的 值,或者讓其保持 不變; 但絕不能用 .org 來讓位置計(jì) 數(shù)器 倒退 。注意 ,位置計(jì) 數(shù)器的起 始值 是相對(duì)于一個(gè)節(jié)的開 始的,而不是子節(jié)的開 始。當(dāng) 位置計(jì)數(shù)器被 提升 后,中間 位置 的 字節(jié) 被填充值fill(這也是一個(gè)常量表達(dá)式)。如果逗號(hào) 和fill都省略 ,則 fill的缺省值 為 0。例如: .org 0x2000ENTRY(pg0)表示把位置計(jì) 數(shù)器 置為 0x2000 ,這個(gè) 位置 存放的就是 臨時(shí)頁表 pg0。三、 Gcc 嵌入
22、式匯編在 Linux 的源代碼中,有很多C 語言的函數(shù)中嵌入一段匯編語言程序段,這就是gcc提供 的“ asm”功 能,例如在include/asm-i386/system.h中定 義的,讀 控制寄存器CR0的一個(gè) 宏 read_cr0() :)這種形式看起來比較陌生 ,這是因?yàn)檫@不是標(biāo)準(zhǔn) C所定 義的形式,而是gcc 對(duì) C語言的擴(kuò) 充 。其中 _dummy為 C 函數(shù)所定 義的變量; 關(guān)鍵詞 _asm_表示匯編代碼的開始。括弧中第一個(gè) 引號(hào) 中為匯編指令 movl ,緊接著有一個(gè) 冒號(hào) ,這種形式閱讀起來比較 復(fù)雜 。一般而言,嵌入式匯編語言片段比單 純的匯編語言代碼要 復(fù)雜 得多,因?yàn)檫@
23、里存在怎樣分 配和使用寄存器,以及把 C 代碼中的 變量 應(yīng)該存放在哪個(gè)寄存器中。 為了 達(dá)到這個(gè)目的,就必須對(duì)一般的 C 語言進(jìn) 行擴(kuò)充, 增加 對(duì)編 譯 器的指 導(dǎo) 作用,因此,嵌入式匯編看起來晦澀而難以讀懂。1. 嵌入式匯編的一 般形式:_asm_ _volatile_ ("<asm routine>" : output : input : modify);其中, _asm_表示匯編代碼的開始,其后可以跟 _volatile_(這是可選項(xiàng)),其含義 是避免 “ asm”指令被 刪除 、移 動(dòng)或 組合 ;然后就是 小括弧,括 弧中的內(nèi)容是我們介紹的重點(diǎn):
24、183;"<asm routine>"為匯編指令部分,例如,"movl %cr0,%0nt"。數(shù)字前加前綴“,如 1, 2 等表示使用寄存器的樣 板操作數(shù)。 可以使用的操作數(shù)總數(shù)取決于具體 CPU中通用寄存器的數(shù)量,如 Intel 可以有8 個(gè)。指令中有幾個(gè)操作數(shù),就說明 有幾個(gè) 變量需要與寄存器結(jié)合,由 gcc 在編 譯時(shí)根據(jù) 后面 輸出部分和 輸入部分的 約束條 件進(jìn)行相應(yīng)的處理。 由于這些樣 板操作數(shù)的前綴使用了”“,因此,在用到具體的寄存器時(shí)就在前面 加兩個(gè)“”,如 %cr0。·輸出部分( output ),用以 規(guī)定對(duì) 輸
25、 出變量 (目 標(biāo)操作數(shù))如 何與寄存器 結(jié)合的 約束( constraint ) ,輸出部分可以有多個(gè)約束,互相以逗號(hào)分開。每個(gè)約束以“ ”開頭,接 著用一個(gè) 字母 來表 示操作數(shù)的 類型 ,然后是關(guān)于 變量結(jié) 合的 約束 。例如,上例中::"=r" (_dummy)“ r ” 表示相應(yīng)的目 標(biāo)操作數(shù)(指令部分的%0)可以使用任何 一個(gè)通用寄存器,并且變量 _dummy 存放在這個(gè)寄存器中,但如果是:“ m” ( _dummy)“ m” 就表 示相應(yīng)的目 標(biāo)操作數(shù)是存放在內(nèi)存單元 _dummy中。表示約束條 件的 字母 很多,表2 5 給出幾個(gè)主要的約束字母 及其 含義
26、:表 2.5主要的 約束字母 及其 含義字母含義m, v,o表示內(nèi)存單元R表示任何 通用寄存器Q表示寄存器 eax, ebx, ecx,edx之一I, h表示直 接操作數(shù)E, F表示浮點(diǎn) 數(shù)G表示“任意 ”a, b.c d表示要求使用寄存器eax/ax/al, ebx/bx/bl, ecx/cx/cl或 edx/dx/dlS, D表示要求使用寄存器esi 或 ediI表示常數(shù)( 0 31)·輸入部分( Input ): 輸入部分與 輸出部分相 似 ,但沒有“ ”。如果 輸入部分一個(gè)操作數(shù)所要求使用的寄存器,與前面輸出部分某個(gè)約束 所要 求的是同一個(gè)寄存器,那就把對(duì)應(yīng)操作數(shù)的編號(hào)(如“
27、 1”,“ 2” 等) 放在約束條 件中,在后面的例子中我們 會(huì)看到這種情 況。·修改 部分( modify ) :這部分常常以“memory ”為 約束條 件,以表 示操作完成后內(nèi)存中的內(nèi)容已有改變 ,如果 原來某個(gè)寄存器的內(nèi)容來自內(nèi)存,那么現(xiàn)在內(nèi)存中這個(gè)單元的內(nèi)容已經(jīng)改變 。注意 ,指令部分為必選項(xiàng),而 輸入部分、輸出部分及 修改 部分為可選 項(xiàng),當(dāng) 輸入部分存在,而 輸 出部分不存在時(shí),分號(hào) “:“要 保留 ,當(dāng)“ memory ”存在時(shí), 三個(gè)分 號(hào)都要 保留 ,例如 system.h 中的 宏定義 _cli():#define _cli()_asm_ _volatile_(
28、"cli": : :"memory")2. Linux 源代碼中嵌入式匯編 舉例Linux 源代碼中,在arch 目錄下的 .h 和 .c 文件中,很多文件都涉及嵌入式匯編,下面以 system.h 中的 C函數(shù)為例, 說明 嵌入式匯編的應(yīng)用。( 1)簡(jiǎn)單應(yīng)用#define _save_flags(x)_asm_ _volatile_("pushfl ; popl %0":"=g" (x):/* no input */)#define _restore_flags(x)_asm_ _volatile_("
29、pushl %0 ; popfl": /* nooutput */:"g" (x):"memory", "cc")第一個(gè) 宏是 保存標(biāo)志 寄存器的 值,第二個(gè) 宏是 恢復(fù)標(biāo)志 寄存器的 值。第一個(gè) 宏中的pushfl指令是把 標(biāo)志 寄存器的 值壓棧 。而 popl 是把 棧頂 的值(剛壓 入棧的 flags )彈出到x 變量 中,這個(gè) 變量 可以存 放在一個(gè)寄存器或內(nèi)存中。這樣,你可以很容易地讀懂第二個(gè)宏。(2) 較復(fù)雜 應(yīng)用static inline unsigned long get_limit(unsigned lon
30、g segment)unsigned long _limit;_asm_("lsll %1,%0":"=r" (_limit):"r" (segment);return _limit+1;這是一個(gè) 設(shè)置 段界限 的函數(shù),匯編代碼段中的輸出參數(shù)為_limit%0(即 ),輸入?yún)?shù)為 segment(即 %1)。 Lsll 是加載 段界限 的指令,即把segment 段描述 符中的段 界限字段裝入某個(gè)寄存器(這個(gè)寄存器與_limit 結(jié)合),函數(shù)返回 _limit加 1,即段長(zhǎng)。(3)復(fù)雜 應(yīng)用在 Linux 內(nèi) 核代碼中,有關(guān)字符串操作的函數(shù)都是通過嵌入式匯編完成的,因?yàn)閮?nèi)核及用 戶程序?qū)?字符串函數(shù)的調(diào)用非常頻繁,因此,用匯編代碼實(shí)現(xiàn)主要是為了提高效率(當(dāng)然是以 犧牲 可讀 性和可 維護(hù)性 為代 價(jià)的)。在此,我們僅列舉一個(gè) 字符串比較函數(shù)strcmp ,其代碼在arch/i386 string.h中。static inline int strcmp(const char * cs,const char * ct)int d0, d1;register int _res;_asm_ _volatile_("1
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年甘肅工業(yè)職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)傾向性測(cè)試題庫匯編
- 科技企業(yè)創(chuàng)新能力的培育與提升策略
- 2025年廣東理工職業(yè)學(xué)院?jiǎn)握新殬I(yè)傾向性測(cè)試題庫完美版
- 2025年海南健康管理職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)技能測(cè)試題庫新版
- 2025年甘肅省慶陽地區(qū)單招職業(yè)適應(yīng)性測(cè)試題庫帶答案
- 科技企業(yè)如何利用輿情分析提升品牌形象
- 2025上海市建筑安全員-C證考試題庫
- SMIC ERP BPR項(xiàng)目軟件版本升級(jí)正式變更 額外變更 5-1-001-某大型企業(yè)SAP ERP方案1
- 外墻改造合同范本
- SMIC ERP BPR項(xiàng)目軟件版本升級(jí)模擬變更 標(biāo)準(zhǔn)程序變更 1-3-104-某大型企業(yè)SAP ERP方案58
- 小學(xué)五年級(jí)奧數(shù)競(jìng)賽試題(含答案)
- Unit-3-Reading-and-thinking課文詳解課件-高中英語人教版必修第二冊(cè)
- 品牌服裝設(shè)計(jì)課件
- 小學(xué)六年級(jí)美術(shù)期末試卷及答案課件
- DB11T 381-2023既有居住建筑節(jié)能改造技術(shù)規(guī)程
- NB-T 47013.7-2012(JB-T 4730.7) 4730.7 承壓設(shè)備無損檢測(cè) 第7部分:目視檢測(cè)
- 統(tǒng)編版高中語文必修下冊(cè) 第一單元單元學(xué)習(xí)任務(wù) 課件
- 新版出口報(bào)關(guān)單模板
- 幼兒園衛(wèi)生保健十三種表格
- 大灰狼兒童睡前故事大全
- 家長(zhǎng)進(jìn)課堂--小學(xué)生食品安全知識(shí)
評(píng)論
0/150
提交評(píng)論