青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

milkyway的窩

最初想法的誕生地

 

[轉(zhuǎn)]Linux 中 x86 的內(nèi)聯(lián)匯編

作者
Bharata?B.?Rao
IBM?Linux?技術(shù)中心,IBM?軟件實(shí)驗(yàn)室,印度
2001?年?3?月?

Bharata?B.?Rao?提供了在?Linux?平臺(tái)上使用和構(gòu)造?x86?內(nèi)聯(lián)匯編的概括性介紹。他介紹了內(nèi)聯(lián)匯編及其各種用法的基礎(chǔ)知識(shí),提供了一些基本的內(nèi)聯(lián)匯編編碼指導(dǎo),并解釋了在?Linux?內(nèi)核中內(nèi)聯(lián)匯編代碼的一些實(shí)例。
如果您是?Linux?內(nèi)核的開發(fā)人員,您會(huì)發(fā)現(xiàn)自己經(jīng)常要對與體系結(jié)構(gòu)高度相關(guān)的功能進(jìn)行編碼或優(yōu)化代碼路徑。您很可能是通過將匯編語言指令插入到?C?語句的中間(又稱為內(nèi)聯(lián)匯編的一種方法)來執(zhí)行這些任務(wù)的。讓我們看一下?Linux?中內(nèi)聯(lián)匯編的特定用法。(我們將討論限制在?IA32?匯編。)

GNU?匯編程序簡述
讓我們首先看一下?Linux?中使用的基本匯編程序語法。GCC(用于?Linux?的?GNU?C?編譯器)使用?AT&T?匯編語法。下面列出了這種語法的一些基本規(guī)則。(該列表肯定不完整;只包括了與內(nèi)聯(lián)匯編相關(guān)的那些規(guī)則。)

寄存器命名?
寄存器名稱有?%?前綴。即,如果必須使用?eax,它應(yīng)該用作?%eax。?

源操作數(shù)和目的操作數(shù)的順序?
在所有指令中,先是源操作數(shù),然后才是目的操作數(shù)。這與將源操作數(shù)放在目的操作數(shù)之后的?Intel?語法不同。?



mov?%eax,?%ebx,?transfers?the?contents?of?eax?to?ebx.

?

操作數(shù)大小?
根據(jù)操作數(shù)是字節(jié)?(byte)、字?(word)?還是長型?(long),指令的后綴可以是?b、w?或?l。這并不是強(qiáng)制性的;GCC?會(huì)嘗試通過讀取操作數(shù)來提供相應(yīng)的后綴。但手工指定后綴可以改善代碼的可讀性,并可以消除編譯器猜測不正確的可能性。?




movb?%al,?%bl?--?Byte?move
????movw?%ax,?%bx?--?Word?move
????movl?%eax,?%ebx?--?Longword?move

?

立即操作數(shù)?
通過使用?$?指定直接操作數(shù)。?



movl?$0xffff,?%eax?--?will?move?the?value?of?0xffff?into?eax?register.

?

間接內(nèi)存引用?
任何對內(nèi)存的間接引用都是通過使用?(??來完成的。?

movb?(%esi),?%al?--?will?transfer?the?byte?in?the?memory?










?pointed?by?esi?into?al
register

?

內(nèi)聯(lián)匯編
GCC?為內(nèi)聯(lián)匯編提供特殊結(jié)構(gòu),它具有以下格式:

GCG?的?"asm"?結(jié)構(gòu)?

???asm?(?assembler?template
????

:?output?operands???????????????(optional)
????

:?input?operands????????????????(optional)
????

:?list?of?clobbered?registers???
????(optional)
????

);??

?

本例中,匯編程序模板由匯編指令組成。輸入操作數(shù)是充當(dāng)指令輸入操作數(shù)使用的?C?表達(dá)式。輸出操作數(shù)是將對其執(zhí)行匯編指令輸出的?C?表達(dá)式。

內(nèi)聯(lián)匯編的重要性體現(xiàn)在它能夠靈活操作,而且可以使其輸出通過?C?變量顯示出來。因?yàn)樗哂羞@種能力,所以?"asm"?可以用作匯編指令和包含它的?C?程序之間的接口。

一個(gè)非常基本但很重要的區(qū)別在于?簡單內(nèi)聯(lián)匯編只包括指令,而?擴(kuò)展內(nèi)聯(lián)匯編包括操作數(shù)。要說明這一點(diǎn),考慮以下示例:?

內(nèi)聯(lián)匯編的基本要素?

{
????int?a=10,?b;
????asm?("movl?%1,?%%eax;
????


movl?%%eax,?%0;"
????????:"=r"(b)??/*?output?*/????
????????:"r"(a)???????/*?input?*/
????????:"%eax";?/*?clobbered?register?*/
}

?

在上例中,我們使用匯編指令使?"b"?的值等于?"a"。請注意以下幾點(diǎn):

"b"?是輸出操作數(shù),由?%0?引用,"a"?是輸入操作數(shù),由?%1?引用。?
"r"?是操作數(shù)的約束,它指定將變量?"a"?和?"b"?存儲(chǔ)在寄存器中。請注意,輸出操作數(shù)約束應(yīng)該帶有一個(gè)約束修飾符?"=",指定它是輸出操作數(shù)。?
要在?"asm"?內(nèi)使用寄存器?%eax,%eax?的前面應(yīng)該再加一個(gè)?%,換句話說就是?%%eax,因?yàn)?"asm"?使用?%0、%1?等來標(biāo)識(shí)變量。任何帶有一個(gè)?%?的數(shù)都看作是輸入/輸出操作數(shù),而不認(rèn)為是寄存器。?
第三個(gè)冒號后的修飾寄存器?%eax?告訴將在?"asm"?中修改?GCC?%eax?的值,這樣?GCC?就不使用該寄存器存儲(chǔ)任何其它的值。?
movl?%1,?%%eax?將?"a"?的值移到?%eax?中,?movl?%%eax,?%0?將?%eax?的內(nèi)容移到?"b"?中。?
因?yàn)?"b"?被指定成輸出操作數(shù),因此當(dāng)?"asm"?的執(zhí)行完成后,它將反映出更新的值。換句話說,對?"asm"?內(nèi)?"b"?所做的更改將在?"asm"?外反映出來。?
現(xiàn)在讓我們更詳細(xì)的了解每一項(xiàng)的含義。

匯編程序模板
匯編程序模板是一組插入到?C?程序中的匯編指令(可以是單個(gè)指令,也可以是一組指令)。每條指令都應(yīng)該由雙引號括起,或者整組指令應(yīng)該由雙引號括起。每條指令還應(yīng)該用一個(gè)定界符結(jié)尾。有效的定界符為新行?(\n)?和分號?(。?'\n'?后可以跟一個(gè)?tab(\t)?作為格式化符號,增加?GCC?在匯編文件中生成的指令的可讀性。?指令通過數(shù)?%0、%1?等來引用?C?表達(dá)式(指定為操作數(shù))。

如果希望確保編譯器不會(huì)在?"asm"?內(nèi)部優(yōu)化指令,可以在?"asm"?后使用關(guān)鍵字?"volatile"。如果程序必須與?ANSI?C?兼容,則應(yīng)該使用?__asm__?和?__volatile__,而不是?asm?和?volatile。

操作數(shù)
C?表達(dá)式用作?"asm"?內(nèi)的匯編指令操作數(shù)。在匯編指令通過對?C?程序的?C?表達(dá)式進(jìn)行操作來執(zhí)行有意義的作業(yè)的情況下,操作數(shù)是內(nèi)聯(lián)匯編的主要特性。

每個(gè)操作數(shù)都由操作數(shù)約束字符串指定,后面跟用括弧括起的?C?表達(dá)式,例如:"constraint"?(C?expression)。操作數(shù)約束的主要功能是確定操作數(shù)的尋址方式。

可以在輸入和輸出部分中同時(shí)使用多個(gè)操作數(shù)。每個(gè)操作數(shù)由逗號分隔開。

在匯編程序模板內(nèi)部,操作數(shù)由數(shù)字引用。如果總共有?n?個(gè)操作數(shù)(包括輸入和輸出),那么第一個(gè)輸出操作數(shù)的編號為?0,逐項(xiàng)遞增,最后那個(gè)輸入操作數(shù)的編號為?n?-1。總操作數(shù)的數(shù)目限制在?10,如果機(jī)器描述中任何指令模式中的最大操作數(shù)數(shù)目大于?10,則使用后者作為限制。?

修飾寄存器列表
如果?"asm"?中的指令指的是硬件寄存器,可以告訴?GCC?我們將自己使用和修改它們。這樣,GCC?就不會(huì)假設(shè)它裝入到這些寄存器中的值是有效值。通常不需要將輸入和輸出寄存器列為?clobbered,因?yàn)?GCC?知道?"asm"?使用它們(因?yàn)樗鼈儽幻鞔_指定為約束)。不過,如果指令使用任何其它的寄存器,無論是明確的還是隱含的(寄存器不在輸入約束列表中出現(xiàn),也不在輸出約束列表中出現(xiàn)),寄存器都必須被指定為修飾列表。修飾寄存器列在第三個(gè)冒號之后,其名稱被指定為字符串。

至于關(guān)鍵字,如果指令以某些不可預(yù)知且不明確的方式修改了內(nèi)存,則可能將?"memory"?關(guān)鍵字添加到修飾寄存器列表中。這樣就告訴?GCC?不要在不同指令之間將內(nèi)存值高速緩存在寄存器中。

操作數(shù)約束
前面提到過,"asm"?中的每個(gè)操作數(shù)都應(yīng)該由操作數(shù)約束字符串描述,后面跟用括弧括起的?C?表達(dá)式。操作數(shù)約束主要是確定指令中操作數(shù)的尋址方式。約束也可以指定:

是否允許操作數(shù)位于寄存器中,以及它可以包括在哪些種類的寄存器中?
操作數(shù)是否可以是內(nèi)存引用,以及在這種情況下使用哪些種類的地址?
操作數(shù)是否可以是立即數(shù)?
約束還要求兩個(gè)操作數(shù)匹配。

常用約束
在可用的操作數(shù)約束中,只有一小部分是常用的;下面列出了這些約束以及簡要描述。有關(guān)操作數(shù)約束的完整列表,請參考?GCC?和?GAS?手冊。

寄存器操作數(shù)約束?(r)?
使用這種約束指定操作數(shù)時(shí),它們存儲(chǔ)在通用寄存器中。請看下例:?



asm?("movl?%%cr3,?%0\n"?:"=r"(cr3val));

?

這里,變量?cr3val?保存在寄存器中,%cr3?的值復(fù)制到寄存器上,cr3val?的值從該寄存器更新到內(nèi)存中。指定?"r"?約束時(shí),GCC?可以將變量?cr3val?保存在任何可用的?GPR?中。要指定寄存器,必須通過使用特定的寄存器約束直接指定寄存器名。



a???%eax

b???%ebx

c???%ecx

d???%edx

S???%esi

D???%edi

?

內(nèi)存操作數(shù)約束?(m)?
當(dāng)操作數(shù)位于內(nèi)存中時(shí),任何對它們執(zhí)行的操作都將在內(nèi)存位置中直接發(fā)生,這與寄存器約束正好相反,后者先將值存儲(chǔ)在要修改的寄存器中,然后將它寫回內(nèi)存位置中。但寄存器約束通常只在對于指令來說它們是絕對必需的,或者它們可以大大提高進(jìn)程速度時(shí)使用。當(dāng)需要在?"asm"?內(nèi)部更新?C?變量,而您又確實(shí)不希望使用寄存器來保存其值時(shí),使用內(nèi)存約束最為有效。例如,idtr?的值存儲(chǔ)在內(nèi)存位置?loc?中:?



?("sidt?%0\n"?:?:"m"(loc));


?

匹配(數(shù)字)約束?
在某些情況下,一個(gè)變量既要充當(dāng)輸入操作數(shù),也要充當(dāng)輸出操作數(shù)。可以通過使用匹配約束在?"asm"?中指定這種情況。?



asm?("incl?%0"?:"=a"(var):"0"(var));

?

在匹配約束的示例中,寄存器?%eax?既用作輸入變量,也用作輸出變量。將?var?輸入讀取到?%eax,增加后將更新的?%eax?再次存儲(chǔ)在?var?中。這里的?"0"?指定第?0?個(gè)輸出變量相同的約束。即,它指定?var?的輸出實(shí)例只應(yīng)該存儲(chǔ)在?%eax?中。該約束可以用于以下情況:

輸入從變量中讀取,或者變量被修改后,修改寫回到同一變量中?
不需要將輸入操作數(shù)和輸出操作數(shù)的實(shí)例分開?
使用匹配約束最重要的意義在于它們可以導(dǎo)致有效地使用可用寄存器

一般內(nèi)聯(lián)匯編用法示例
以下示例通過各種不同的操作數(shù)約束說明了用法。有如此多的約束以至于無法將它們一一列出,這里只列出了最經(jīng)常使用的那些約束類型。

"asm"?和寄存器約束?"r"?讓我們先看一下使用寄存器約束?r?的?"asm"。我們的示例顯示了?GCC?如何分配寄存器,以及它如何更新輸出變量的值。?

int?main(void)
{
????int?x?=?10,?y;
????
????asm?("movl?%1,?%%eax;
????

?"movl?%%eax,?%0;"
????????:"=r"(y)??/*?y?is?output?operand?*/
????????:"r"(x)???????/*?x?is?input?operand?*/
????????:"%eax";?/*?%eax?is?clobbered?register?*/
}


?

在該例中,x?的值復(fù)制為?"asm"?中的?y。x?和?y?都通過存儲(chǔ)在寄存器中傳遞給?"asm"。為該例生成的匯編代碼如下:



main:




pushl?%ebp




movl?%esp,%ebp




subl?$8,%esp




movl?$10,-4(%ebp)????




movl?-4(%ebp),%edx??/*?x=10?is?stored?in?%edx?*/
#APP????/*?asm?starts?here?*/???




movl?%edx,?%eax?????/*?x?is?moved?to?%eax?*/




movl?%eax,?%edx?????/*?y?is?allocated?in?edx?and?updated?*/

#NO_APP?/*?asm?ends?here?*/




movl?%edx,-8(%ebp)??/*?value?of?y?in?stack?is?updated?with?
????????????????
?the?value?in?%edx?*/?

?

當(dāng)使用?"r"?約束時(shí),GCC?在這里可以自由分配任何寄存器。在我們的示例中,它選擇?%edx?來存儲(chǔ)?x。在讀取了?%edx?中?x?的值后,它為?y?也分配了相同的寄存器

因?yàn)?y?是在輸出操作數(shù)部分中指定的,所以?%edx?中更新的值存儲(chǔ)在?-8(%ebp),堆棧上?y?的位置中。如果?y?是在輸入部分中指定的,那么即使它在?y?的臨時(shí)寄存器存儲(chǔ)值?(%edx)?中被更新,堆棧上?y?的值也不會(huì)更新。

因?yàn)?%eax?是在修飾列表中指定的,GCC?不在任何其它地方使用它來存儲(chǔ)數(shù)據(jù)。

輸入?x?和輸出?y?都分配在同一個(gè)?%edx?寄存器中,假設(shè)輸入在輸出產(chǎn)生之前被消耗。請注意,如果您有許多指令,就不是這種情況了。要確保輸入和輸出分配到不同的寄存器中,可以指定?&?約束修飾符。下面是添加了約束修飾符的示例。



int?main(void)
{
????int?x?=?10,?y;
????
????asm?("movl?%1,?%%eax;
????

?"movl?%%eax,?%0;"
????????:"=&r"(y)?/*?y?is?output?operand,?note?the????
????????????????
?&?constraint?modifier.?*/
????????:"r"(x)???????/*?x?is?input?operand?*/
????????:"%eax";?/*?%eax?is?clobbered?register?*/
}

?

以下是為該示例生成的匯編代碼,從中可以明顯地看出?x?和?y?存儲(chǔ)在?"asm"?中不同的寄存器中。



main:




pushl?%ebp




movl?%esp,%ebp




subl?$8,%esp




movl?$10,-4(%ebp)




movl?-4(%ebp),%ecx??/*?x,?the?input?is?in?%ecx?*/
#APP
????movl?%ecx,?%eax
????movl?%eax,?%edx?????/*?y,?the?output?is?in?%edx?*/

#NO_APP




movl?%edx,-8(%ebp)

?

特定寄存器約束的使用
現(xiàn)在讓我們看一下如何將個(gè)別寄存器作為操作數(shù)的約束指定。在下面的示例中,cpuid?指令采用?%eax?寄存器中的輸入,然后在四個(gè)寄存器中給出輸出:%eax、%ebx、%ecx、%edx。對?cpuid?的輸入(變量?"op")傳遞到?"asm"?的?eax?寄存器中,因?yàn)?cpuid?希望它這樣做。在輸出中使用?a、b、c?和?d?約束,分別收集四個(gè)寄存器中的值。



asm?("cpuid"








:?"=a"?(_eax),









"=b"?(_ebx),









"=c"?(_ecx),









"=d"?(_edx)








:?"a"?(op));


?

在下面可以看到為它生成的匯編代碼(假設(shè)?_eax、_ebx?等...?變量都存儲(chǔ)在堆棧上):




movl?-20(%ebp),%eax?/*?store?'op'?in?%eax?--?input?*/
#APP




cpuid
#NO_APP




movl?%eax,-4(%ebp)??/*?store?%eax?in?_eax?--?output?*/




movl?%ebx,-8(%ebp)??/*?store?other?registers?in




movl?%ecx,-12(%ebp)?
?respective?output?variables?*/





movl?%edx,-16(%ebp)

?

strcpy?函數(shù)可以通過以下方式使用?"S"?和?"D"?約束來實(shí)現(xiàn):



asm?("cld\n
????


rep\n
????


movsb"
????


:?/*?no?input?*/
????


:"S"(src),?"D"(dst),?"c"(count));

?

通過使用?"S"?約束將源指針?src?放入?%esi?中,使用?"D"?約束將目的指針?dst?放入?%edi?中。因?yàn)?rep?前綴需要?count?值,所以將它放入?%ecx?中。

在下面可以看到另一個(gè)約束,它使用兩個(gè)寄存器?%eax?和?%edx?將兩個(gè)?32?位的值合并在一起,然后生成一個(gè)64?位的值:


#define?rdtscll(val)?\


?__asm__?__volatile__?("rdtsc"?:?"=A"?(val))

The?generated?assembly?looks?like?this?(if?val?has?a?64?bit?memory?space).

#APP




rdtsc
#NO_APP




movl?%eax,-8(%ebp)??/*?As?a?result?of?A?constraint?




movl?%edx,-4(%ebp)??
?%eax?and?%edx?serve?as?outputs?*/

Note?here?that?the?values?in?%edx:%eax?serve?as?64?bit?output.

?

使用匹配約束
在下面將看到系統(tǒng)調(diào)用的代碼,它有四個(gè)參數(shù):



#define?_syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)?\
type?name?(type1?arg1,?type2?arg2,?type3?arg3,?type4?arg4)?\
{?\
long?__res;?\
__asm__?volatile?("int?$0x80"?\




:?"=a"?(__res)?\




:?"0"?(__NR_##name),"b"?((long)(arg1)),"c"?((long)(arg2)),?\





"d"?((long)(arg3)),"S"?((long)(arg4)));?\
__syscall_return(type,__res);?\
}

?

在上例中,通過使用?b、c、d?和?S?約束將系統(tǒng)調(diào)用的四個(gè)自變量放入?%ebx、%ecx、%edx?和?%esi?中。請注意,在輸出中使用了?"=a"?約束,這樣,位于?%eax?中的系統(tǒng)調(diào)用的返回值就被放入變量?__res?中。通過將匹配約束?"0"?用作輸入部分中第一個(gè)操作數(shù)約束,syscall?號?__NR_##name?被放入?%eax?中,并用作對系統(tǒng)調(diào)用的輸入。這樣,這里的?%eax?既可以用作輸入寄存器,又可以用作輸出寄存器。沒有其它寄存器用于這個(gè)目的。另請注意,輸入(syscall?號)在產(chǎn)生輸出(syscall?的返回值)之前被消耗(使用)。

內(nèi)存操作數(shù)約束的使用
請考慮下面的原子遞減操作:



__asm__?__volatile__(








"lock;?decl?%0"








:"=m"?(counter)








:"m"?(counter));

?

為它生成的匯編類似于:



#APP
????lock
????decl?-24(%ebp)?/*?counter?is?modified?on?its?memory?location?*/
#NO_APP.

?

您可能考慮在這里為?counter?使用寄存器約束。如果這樣做,counter?的值必須先復(fù)制到寄存器,遞減,然后對其內(nèi)存更新。但這樣您會(huì)無法理解鎖定和原子性的全部意圖,這些明確顯示了使用內(nèi)存約束的必要性。

使用修飾寄存器
請考慮內(nèi)存拷貝的基本實(shí)現(xiàn)。

???asm?("movl?$count,?%%ecx;
????


up:?lodsl;??
????


stosl;
????


loop?up;"
????????:???????????/*?no?output?*/
????????:"S"(src),?"D"(dst)?/*?input?*/
????????:"%ecx",?"%eax"?;??/*?clobbered?list?*/????

?

當(dāng)?lodsl?修改?%eax?時(shí),lodsl?和?stosl?指令隱含地使用它。%ecx?寄存器明確裝入?count。但?GCC?在我們通知它以前是不知道這些的,我們是通過將?%eax?和?%ecx?包括在修飾寄存器集中來通知?GCC?的。在完成這一步之前,GCC?假設(shè)?%eax?和?%ecx?是自由的,它可能決定將它們用作存儲(chǔ)其它的數(shù)據(jù)。請注意,%esi?和?%edi?由?"asm"?使用,它們不在修飾列表中。這是因?yàn)橐呀?jīng)聲明?"asm"?將在輸入操作數(shù)列表中使用它們。這里最低限度是,如果在?"asm"?內(nèi)部使用寄存器(無論是明確還是隱含地),既不出現(xiàn)在輸入操作數(shù)列表中,也不出現(xiàn)在輸出操作數(shù)列表中,必須將它列為修飾寄存器

結(jié)束語
總的來說,內(nèi)聯(lián)匯編非常巨大,它提供的許多特性我們甚至在這里根本沒有涉及到。但如果掌握了本文描述的基本材料,您應(yīng)該可以開始對自己的內(nèi)聯(lián)匯編進(jìn)行編碼了。

參考資料?

您可以參閱本文在?developerWorks?全球站點(diǎn)上的?英文原文.?


請參考?Using?and?Porting?the?GNU?Compiler?Collection?(GCC)手冊。?


請參考?GNU?Assembler?(GAS)手冊。?


仔細(xì)閱讀?Brennan's?Guide?to?Inline?Assembly。?


關(guān)于作者
Bharata?B.?Rao?擁有印度?Mysore?大學(xué)的電子和通信工程的學(xué)士學(xué)位。他從?1999?年就開始為?IBM?Global?Services,?India?工作了。他是?IBM?Linux?技術(shù)中心的成員之一,他在該中心中主要從事?Linux?RAS(可靠性、可用性和適用性)的研究。他感興趣的其它領(lǐng)域包括操作系統(tǒng)本質(zhì)和處理器體系結(jié)構(gòu)。可以通過?rbharata@in.ibm.com?與他聯(lián)系。??

posted on 2007-01-02 13:48 milkyway 閱讀(577) 評論(0)  編輯 收藏 引用 所屬分類: linux

導(dǎo)航

統(tǒng)計(jì)

公告

隨筆皆原創(chuàng),文章乃轉(zhuǎn)載. 歡迎留言!

常用鏈接

留言簿(37)

隨筆分類(104)

隨筆檔案(101)

文章分類(51)

文章檔案(53)

wince牛人

搜索

積分與排名

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久精品成人一区二区三区 | 欧美一级大片在线免费观看| 国产午夜精品一区二区三区视频| 欧美日韩在线一区二区| 欧美亚洲一区二区在线| 小嫩嫩精品导航| 香蕉精品999视频一区二区| 中日韩高清电影网| 99这里只有精品| 9i看片成人免费高清| 91久久香蕉国产日韩欧美9色| 久久久久久国产精品mv| 欧美一区二区三区四区视频| 久久精品女人的天堂av| 亚洲午夜激情| 欧美一区二区三区免费观看| 欧美在线播放| 久久久噜噜噜久噜久久| 久久久91精品国产| 欧美激情欧美激情在线五月| 亚洲日本aⅴ片在线观看香蕉| 欧美肥婆在线| 一区二区三区四区五区在线| 久久成人免费电影| 欧美日韩一区二区在线观看| 国产日韩在线一区| 亚洲裸体视频| 欧美专区在线| 亚洲欧洲精品一区二区精品久久久 | 日韩网站在线| 亚洲欧美精品中文字幕在线| 久久久亚洲国产天美传媒修理工| 亚洲高清不卡在线| 亚洲男人的天堂在线| 久久野战av| 国产日韩欧美自拍| 亚洲香蕉在线观看| 亚洲国产精品va在看黑人| 亚洲欧美另类在线观看| 欧美福利视频在线观看| 狠狠色狠狠色综合| 午夜精品一区二区三区在线播放| 亚洲国产一区二区在线| 久久精品五月婷婷| 国产精品尤物| 亚洲图片激情小说| 国产九九精品| 国产日韩欧美综合| 亚洲自拍偷拍色片视频| 欧美成人在线影院| 久久精品国产欧美激情| 国产欧美欧美| 午夜精品免费在线| 亚洲午夜视频在线观看| 欧美精选在线| 99re6热在线精品视频播放速度 | 亚洲激情国产| 老司机免费视频一区二区| 国产亚洲一级高清| 久久精品视频在线播放| 欧美一区午夜精品| 精品福利免费观看| 男女激情久久| 麻豆av一区二区三区| 亚洲福利久久| 亚洲国产黄色| 久久综合一区二区三区| 亚洲第一伊人| 亚洲高清av在线| 欧美久久久久免费| 在线亚洲欧美视频| 日韩视频一区二区三区在线播放| 欧美激情亚洲国产| 亚洲午夜久久久久久久久电影院| 亚洲精品日韩久久| 欧美激情中文不卡| 亚洲婷婷综合色高清在线| 亚洲欧美国产va在线影院| 国产性色一区二区| 欧美成人福利视频| 欧美日韩mp4| 午夜精品在线观看| 久久精品男女| 亚洲精品女人| 亚洲欧美日韩国产综合精品二区| 国产亚洲精品久| 亚洲大胆在线| 欧美三级韩国三级日本三斤| 欧美亚洲在线观看| 久久先锋影音av| 99视频精品| 午夜精品免费视频| 亚洲国产视频一区| 在线视频一区观看| 亚洲高清自拍| 亚洲免费在线看| 亚洲精品免费网站| 午夜欧美理论片| 亚洲精品国精品久久99热一| 亚洲天堂成人在线观看| 激情婷婷久久| 一区二区三区欧美| 玉米视频成人免费看| 99国内精品| 狠狠色狠狠色综合日日tαg| 欧美激情一区二区在线| 国产精品视频网| 欧美日韩国产不卡| 国产亚洲精品v| 亚洲精品一品区二品区三品区| 国产精品分类| 亚洲激情在线播放| 国产欧美亚洲日本| 亚洲另类在线视频| 亚洲国产综合91精品麻豆| 亚洲伊人一本大道中文字幕| 亚洲日本成人女熟在线观看| 欧美一区二区福利在线| 一区二区三区av| 久久亚洲美女| 久久久久久**毛片大全| 国产精品久久久久久久app| 老鸭窝亚洲一区二区三区| 国产精品一区二区你懂的| 亚洲第一页在线| 激情成人综合网| 欧美在线视频网站| 一区二区精品在线| 欧美大尺度在线| 免费观看欧美在线视频的网站| 国产精品人人做人人爽| 亚洲久久在线| 亚洲精品欧美日韩专区| 久久九九国产精品怡红院| 久久激五月天综合精品| 国产精品久久午夜夜伦鲁鲁| 99国产精品国产精品毛片| 亚洲免费观看| 欧美日韩国产一区二区| 亚洲精品乱码久久久久久日本蜜臀| 黄色一区二区三区四区| 欧美伊人久久久久久午夜久久久久| 久久疯狂做爰流白浆xx| 国产亚洲欧美激情| 欧美一区二区在线免费播放| 久久久久五月天| 亚洲高清不卡av| 久久这里只有| 亚洲第一精品夜夜躁人人躁| 在线免费精品视频| 欧美.www| 亚洲福利国产精品| 亚洲一区欧美一区| 国产日韩欧美综合精品| 亚洲一区三区视频在线观看| 国产一区二区高清不卡| 欧美亚洲在线观看| 国产伦精品一区二区三区四区免费 | 欧美www视频| 在线日韩中文字幕| 欧美激情综合在线| 日韩图片一区| 欧美日韩一视频区二区| 在线一区日本视频| 国产视频观看一区| 久久久www免费人成黑人精品| 欧美激情视频网站| 久久久久成人精品免费播放动漫| 欧美大片91| 亚洲欧美另类国产| 亚洲高清二区| 欧美韩日一区| 一区二区三区色| 樱桃国产成人精品视频| 欧美成人一区二区三区| 欧美在线观看网址综合| 一区在线影院| 欧美视频在线视频| 欧美在线免费观看亚洲| 亚洲福利视频一区| 亚洲综合色噜噜狠狠| 国产一区二区三区直播精品电影| 久久久久久久久久久久久女国产乱 | 精品成人在线观看| 欧美视频中文字幕| 久久精品男女| 亚洲午夜久久久久久久久电影网| 久久精品欧美日韩| 亚洲精品女av网站| 韩国av一区二区三区四区| 欧美日韩日日夜夜| 久久久99精品免费观看不卡| 亚洲免费成人| 欧美成人精品1314www| 亚洲一区二区视频| 亚洲美女av电影| 一区二区视频免费完整版观看| 国产精品午夜久久| 欧美日韩视频一区二区| 久久久久久久久蜜桃|