<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 23章 64位化 ## 23.1 x86-64 對x86架構來說這是一個64位的擴展。 從反編譯工程師的角度來看,最重要的區別是: 幾乎所有的寄存器(除了FPU和SIMD)都擴展到了64位,而且都有一個r-前綴,而且還額外添加了8個寄存器。 現在所有的通用寄存器是:RAX、RBX、RCX、RDX、RBP、RSP、RSI、RDI、R8、R9、R10、R11、R12、R13、R14、R15。 當然,還是可以像以前一樣加載舊的寄存器的。比如,使用EAX就可以訪問RAX的低32位部分。 新的R8-R15寄存器也有對應的低位:R8D-R15D(低32位)、R8W-R15W(低16位)、R8B-R15B(低8位)。 SIMD寄存器的數量從8個擴展到了16個:XMM0-XMM15。 在Win64下,函數調用轉換有一些輕微的變化。例如fastcall(見47.3節)。最開始的4個參數將存儲在RCX、RDX、R8和R9寄存器里,其他的保存在棧上。調用者函數必須分配32個字節,因此被調用者可以保存前4個參數,然后再去按照他自己的需要去利用這些寄存器。一些較短的函數可以直接從寄存器里使用參數,但是大點的函數就需要把參數保存到棧上了。 系統V AMD64 ABI(LINUX, *BSD, MAC OS X)也改變了fastcall的方式。它為前6個參數使用了6個寄存器RDI、RSI、RDX、RCX、R8、R9。剩余的參數將傳入棧中。 請看調用轉換(47)一節。 為了保證兼容性,C int類型依然是32位。 ?現在所有的指針都是64位的了。 當然這個有時候很麻煩:因為現在我們需要2倍的空間來存儲指針,包括緩存,而不管事實上64位CPU只會使用48位的擴展內存這個情況。 由于現在寄存器數量翻倍了,編譯器也將有更多的空間來處理寄存器分配的策略。對我們來說,也就是現在提交的代碼將會有更少的本地變量。 例如,DES加密算法中計算第一個S-Box時,使用位切割DES方法(見22章)他將每次處理32/64/128/256個變量(依據DES_type類型(uint32、uint64、SSE2或者AVX))。 ``` #!cpp /* * Generated S-box files. * * This software may be modified, redistributed, and used for any purpose, * so long as its origin is acknowledged. * * Produced by Matthew Kwan - March 1998 */ #ifdef _WIN64 #define DES_type unsigned __int64 #else #define DES_type unsigned int #endif void s1 ( DES_type a1, DES_type a2, DES_type a3, DES_type a4, DES_type a5, DES_type a6, DES_type *out1, DES_type *out2, DES_type *out3, DES_type *out4 ) { DES_type x1, x2, x3, x4, x5, x6, x7, x8; DES_type x9, x10, x11, x12, x13, x14, x15, x16; DES_type x17, x18, x19, x20, x21, x22, x23, x24; DES_type x25, x26, x27, x28, x29, x30, x31, x32; DES_type x33, x34, x35, x36, x37, x38, x39, x40; DES_type x41, x42, x43, x44, x45, x46, x47, x48; DES_type x49, x50, x51, x52, x53, x54, x55, x56; x1 = a3 & ~a5; x2 = x1 ^ a4; x3 = a3 & ~a4; x4 = x3 | a5; x5 = a6 & x4; x6 = x2 ^ x5; x7 = a4 & ~a5; x8 = a3 ^ a4; x9 = a6 & ~x8; x10 = x7 ^ x9; x11 = a2 | x10; x12 = x6 ^ x11; x13 = a5 ^ x5; x14 = x13 & x8; x15 = a5 & ~a4; x16 = x3 ^ x14; x17 = a6 | x16; x18 = x15 ^ x17; x19 = a2 | x18; x20 = x14 ^ x19; x21 = a1 & x20; x22 = x12 ^ ~x21; *out2 ^= x22; x23 = x1 | x5; x24 = x23 ^ x8; x25 = x18 & ~x2; x26 = a2 & ~x25; x27 = x24 ^ x26; x28 = x6 | x7; x29 = x28 ^ x25; x30 = x9 ^ x24; x31 = x18 & ~x30; x32 = a2 & x31; x33 = x29 ^ x32; x34 = a1 & x33; x35 = x27 ^ x34; *out4 ^= x35; x36 = a3 & x28; x37 = x18 & ~x36; x38 = a2 | x3; x39 = x37 ^ x38; x40 = a3 | x31; x41 = x24 & ~x37; x42 = x41 | x3; x43 = x42 & ~a2; x44 = x40 ^ x43; x45 = a1 & ~x44; x46 = x39 ^ ~x45; *out1 ^= x46; x47 = x33 & ~x9; x48 = x47 ^ x39; x49 = x4 ^ x36; x50 = x49 & ~x5; x51 = x42 | x18; x52 = x51 ^ a5; x53 = a2 & ~x52; x54 = x50 ^ x53; x55 = a1 | x54; x56 = x48 ^ ~x55; *out3 ^= x56; } ``` 這兒也有許多本地變量。當然,并不是所有的這些都存在本地棧上。讓我們用MSVC2008的/Ox選項來編譯一下: 清單23.1 使用MSVC 2008編譯 ``` #!bash PUBLIC _s1 ; Function compile flags: /Ogtpy _TEXT SEGMENT _x6$ = -20 ; size = 4 _x3$ = -16 ; size = 4 _x1$ = -12 ; size = 4 _x8$ = -8 ; size = 4 _x4$ = -4 ; size = 4 _a1$ = 8 ; size = 4 _a2$ = 12 ; size = 4 _a3$ = 16 ; size = 4 _x33$ = 20 ; size = 4 _x7$ = 20 ; size = 4 _a4$ = 20 ; size = 4 _a5$ = 24 ; size = 4 tv326 = 28 ; size = 4 _x36$ = 28 ; size = 4 _x28$ = 28 ; size = 4 _a6$ = 28 ; size = 4 _out1$ = 32 ; size = 4 _x24$ = 36 ; size = 4 _out2$ = 36 ; size = 4 _out3$ = 40 ; size = 4 _out4$ = 44 ; size = 4 _s1 PROC sub esp, 20 ; 00000014H mov edx, DWORD PTR _a5$[esp+16] push ebx mov ebx, DWORD PTR _a4$[esp+20] push ebp push esi mov esi, DWORD PTR _a3$[esp+28] push edi mov edi, ebx not edi mov ebp, edi and edi, DWORD PTR _a5$[esp+32] mov ecx, edx not ecx and ebp, esi mov eax, ecx and eax, esi and ecx, ebx mov DWORD PTR _x1$[esp+36], eax xor eax, ebx mov esi, ebp or esi, edx mov DWORD PTR _x4$[esp+36], esi and esi, DWORD PTR _a6$[esp+32] mov DWORD PTR _x7$[esp+32], ecx mov edx, esi xor edx, eax mov DWORD PTR _x6$[esp+36], edx mov edx, DWORD PTR _a3$[esp+32] xor edx, ebx mov ebx, esi xor ebx, DWORD PTR _a5$[esp+32] mov DWORD PTR _x8$[esp+36], edx and ebx, edx mov ecx, edx mov edx, ebx xor edx, ebp or edx, DWORD PTR _a6$[esp+32] not ecx and ecx, DWORD PTR _a6$[esp+32] xor edx, edi mov edi, edx or edi, DWORD PTR _a2$[esp+32] mov DWORD PTR _x3$[esp+36], ebp mov ebp, DWORD PTR _a2$[esp+32] xor edi, ebx and edi, DWORD PTR _a1$[esp+32] mov ebx, ecx xor ebx, DWORD PTR _x7$[esp+32] not edi or ebx, ebp xor edi, ebx mov ebx, edi mov edi, DWORD PTR _out2$[esp+32] xor ebx, DWORD PTR [edi] not eax xor ebx, DWORD PTR _x6$[esp+36] and eax, edx mov DWORD PTR [edi], ebx mov ebx, DWORD PTR _x7$[esp+32] or ebx, DWORD PTR _x6$[esp+36] mov edi, esi or edi, DWORD PTR _x1$[esp+36] mov DWORD PTR _x28$[esp+32], ebx xor edi, DWORD PTR _x8$[esp+36] mov DWORD PTR _x24$[esp+32], edi xor edi, ecx not edi and edi, edx mov ebx, edi and ebx, ebp xor ebx, DWORD PTR _x28$[esp+32] xor ebx, eax not eax mov DWORD PTR _x33$[esp+32], ebx and ebx, DWORD PTR _a1$[esp+32] and eax, ebp xor eax, ebx mov ebx, DWORD PTR _out4$[esp+32] xor eax, DWORD PTR [ebx] xor eax, DWORD PTR _x24$[esp+32] mov DWORD PTR [ebx], eax mov eax, DWORD PTR _x28$[esp+32] and eax, DWORD PTR _a3$[esp+32] mov ebx, DWORD PTR _x3$[esp+36] or edi, DWORD PTR _a3$[esp+32] mov DWORD PTR _x36$[esp+32], eax not eax and eax, edx or ebx, ebp xor ebx, eax not eax and eax, DWORD PTR _x24$[esp+32] not ebp or eax, DWORD PTR _x3$[esp+36] not esi and ebp, eax or eax, edx xor eax, DWORD PTR _a5$[esp+32] mov edx, DWORD PTR _x36$[esp+32] xor edx, DWORD PTR _x4$[esp+36] xor ebp, edi mov edi, DWORD PTR _out1$[esp+32] not eax and eax, DWORD PTR _a2$[esp+32] not ebp and ebp, DWORD PTR _a1$[esp+32] and edx, esi xor eax, edx or eax, DWORD PTR _a1$[esp+32] not ebp xor ebp, DWORD PTR [edi] not ecx and ecx, DWORD PTR _x33$[esp+32] xor ebp, ebx not eax mov DWORD PTR [edi], ebp xor eax, ecx mov ecx, DWORD PTR _out3$[esp+32] xor eax, DWORD PTR [ecx] pop edi pop esi xor eax, ebx pop ebp mov DWORD PTR [ecx], eax pop ebx add esp, 20 ; 00000014H ret 0 _s1 ENDP ``` 編譯器在本地棧上分配了5個變量。 現在再讓我們在MSVC 2008的64位環境中試一試: 清單23.2 使用MSVC 2008編譯 ``` #!bash a1$ = 56 a2$ = 64 a3$ = 72 a4$ = 80 x36$1$ = 88 a5$ = 88 a6$ = 96 out1$ = 104 out2$ = 112 out3$ = 120 out4$ = 128 s1 PROC $LN3: mov QWORD PTR [rsp+24], rbx mov QWORD PTR [rsp+32], rbp mov QWORD PTR [rsp+16], rdx mov QWORD PTR [rsp+8], rcx push rsi push rdi push r12 push r13 push r14 push r15 mov r15, QWORD PTR a5$[rsp] mov rcx, QWORD PTR a6$[rsp] mov rbp, r8 mov r10, r9 mov rax, r15 mov rdx, rbp not rax xor rdx, r9 not r10 mov r11, rax and rax, r9 mov rsi, r10 mov QWORD PTR x36$1$[rsp], rax and r11, r8 and rsi, r8 and r10, r15 mov r13, rdx mov rbx, r11 xor rbx, r9 mov r9, QWORD PTR a2$[rsp] mov r12, rsi or r12, r15 not r13 and r13, rcx mov r14, r12 and r14, rcx mov rax, r14 mov r8, r14 xor r8, rbx xor rax, r15 not rbx and rax, rdx mov rdi, rax xor rdi, rsi or rdi, rcx xor rdi, r10 and rbx, rdi mov rcx, rdi or rcx, r9 xor rcx, rax mov rax, r13 xor rax, QWORD PTR x36$1$[rsp] and rcx, QWORD PTR a1$[rsp] or rax, r9 not rcx xor rcx, rax mov rax, QWORD PTR out2$[rsp] xor rcx, QWORD PTR [rax] xor rcx, r8 mov QWORD PTR [rax], rcx mov rax, QWORD PTR x36$1$[rsp] mov rcx, r14 or rax, r8 or rcx, r11 mov r11, r9 xor rcx, rdx mov QWORD PTR x36$1$[rsp], rax mov r8, rsi mov rdx, rcx xor rdx, r13 not rdx and rdx, rdi mov r10, rdx and r10, r9 xor r10, rax xor r10, rbx not rbx and rbx, r9 mov rax, r10 and rax, QWORD PTR a1$[rsp] xor rbx, rax mov rax, QWORD PTR out4$[rsp] xor rbx, QWORD PTR [rax] xor rbx, rcx mov QWORD PTR [rax], rbx mov rbx, QWORD PTR x36$1$[rsp] and rbx, rbp mov r9, rbx not r9 and r9, rdi or r8, r11 mov rax, QWORD PTR out1$[rsp] xor r8, r9 not r9 and r9, rcx or rdx, rbp mov rbp, QWORD PTR [rsp+80] or r9, rsi xor rbx, r12 mov rcx, r11 not rcx not r14 not r13 and rcx, r9 or r9, rdi and rbx, r14 xor r9, r15 xor rcx, rdx mov rdx, QWORD PTR a1$[rsp] not r9 not rcx and r13, r10 and r9, r11 and rcx, rdx xor r9, rbx mov rbx, QWORD PTR [rsp+72] not rcx xor rcx, QWORD PTR [rax] or r9, rdx not r9 xor rcx, r8 mov QWORD PTR [rax], rcx mov rax, QWORD PTR out3$[rsp] xor r9, r13 xor r9, QWORD PTR [rax] xor r9, r8 mov QWORD PTR [rax], r9 pop r15 pop r14 pop r13 pop r12 pop rdi pop rsi ret 0 s1 ENDP ``` 編譯器在棧上并沒有分配任何內存空間,x36是a5的同義詞。 順帶一提,我們可以在這兒看到的是,函數在調用者空間中保存了RCX和RDX,但是R8和R9雖然在一開始就使用了,但是卻并沒有保存。 還有,還有擁有更多GPR的CPU,比如Itanium(有128個寄存器)。 ## 23.2 ARM 在ARM中,64位指令在ARMv8中才開始出現。 ## 23.3 浮點數字 見24章以了解更多的x86-64處理器中是如何處理浮點數的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看