Time of Update: 2018-12-07
AND: 邏輯與指令OR : 邏輯或指令XOR: 邏輯異或指令NOT: 邏輯非指令這和 Delphi 的邏輯命令完全一致.//邏輯非 Not: { not 1 = 0; not 0 = 1;}var ByteNum: Byte;begin //賦值 11111111B (255) 取反: asm mov al, 11111111B {eax 包含 ax; ax 包含 al; al 是 eax 的低八位} not al {給 11111111
Time of Update: 2018-12-07
彙編中的SHL(左移)、SHR(右移)命令也是和 Delphi 一樣的.var ByteNum: Byte;begin //右移 shr asm mov al, 10000000B {128} shr al, 1 {shr 10000000 一次會得到 01000000} mov ByteNum, al end; ShowMessage(IntToStr(ByteNum)); {64; shr 相當於 ÷2} //左移 shl asm
Time of Update: 2018-12-07
var B: Byte; W: Word; C: Cardinal;begin {Byte 是1位元組(8位)無符號整型, 其最大值是 111111112} asm mov B, 11111111B; end; ShowMessage(IntToStr(B)); {255} {Word 是2位元組(16位)無符號整型, 其最大值是 11111111 111111112} asm mov W, 1111111111111111B; end;
Time of Update: 2018-12-07
var I: Integer;begin //Integer 類型是4位元組(32位)有符號整數, 最高位是符號位, 如果是正數, 符號位是 0、負數的符號位是1 //所以 Integer 的最大值是: 01111111 11111111 11111111 111111112 asm mov I, 01111111111111111111111111111111B; end; ShowMessage(IntToStr(I)); {2147483647}
Time of Update: 2018-12-07
除了 Byte、Word、Cardinal、Integer 外, Delphi 的整數類型還有:Longint、Longword、Shortint、Smallint、Int64其中 Longint 相當於 Integer; Longword 相當於 Cardinal. 這樣還有三種類型:Shortint、Smallint、Int64//Shortint 是1位元組(8位)有符號整數var I: Shortint;begin //其最大值是: 011111112 asm mov I,
Time of Update: 2018-12-07
//計算 x 的 n 次方的函數function Fun(x,n: Integer): Integer;asm //mov eax, x {因為 eax 會先擷取第一個參數, 這句可以省略} mov ecx, n {ecx 是個計數寄存器, 會記錄迴圈的次數, 每迴圈一次 ecx 的值就會減1} sub ecx, 1 @Lable1: add eax, eax {內部標籤必須使用 @ 首碼; 也可以使用 Delphi 的標籤} loop @
Time of Update: 2018-12-07
類型 助記符 助記符簡寫 所佔位元組數 數值範圍位元組BYTEDB10..255字WORDDW20..65535雙字DWORDDD40..4294967295遠字FWORDDF6 四字QWORDDQ8 十位元組TBYTEDT10 有符號位元組SBYTE 1-128..127有符號字SWORD 1-32768..32767有符號雙字 SDWORD 1-2147483648..2147483647書上抄的, 還沒有測試 Delphi 支援情況.
Time of Update: 2018-12-07
//準備一個在彙編中要調用的函數function DelphiFun(x,y: Integer): Integer;begin Result := x + y;end;//彙編函數function AsmFun: Integer;asm mov eax, 1 {eax 對應函數的第一個參數, 這裡給第一個參數賦值為 1} mov edx, 2 {edx 對應函數的第二個參數, 這裡給第二個參數賦值為 2} call DelphiFun {call 是調用命令;
Time of Update: 2018-12-07
王爽老師書上說, CPU 內部主要就是寄存器.現在我們在 32 位的系統下工作, 當然主要使用的是 32 位寄存器; 那它和 8 位、16 位的寄存器又有什麼關係呢?從網上找到一個簡潔明了的圖片:EAX 是 32 位的, 也就是 4 個位元組大小; 它的低兩位就是 AX;AX 是 16 位的, 又分 2 個位元組; 它的高位元組是 AH、低位元組是 AL;AH 與 AL 是 8 位的.這樣就相容了以前的 16 位與 8 位.同理, EBX 就包含著 BX BH BL;ECX 就包含著 CX
Time of Update: 2018-12-07
傳回型別寄存位置Char、ByteAL 寄存器SmallInt、WordAX 寄存器Integer、LongWord、AnsiString、Pointer、ClassEAX 寄存器Real48EAX 寄存器中是棧內傳回值的指標Int64EDX、EAX 寄存器對Single、Double、Extended、Comp棧首寄存器 ST(0)短字串或變體類型在@Result指向的臨時位置中返回
Time of Update: 2018-12-07
組合語言不區分大小寫.關鍵字用途AHALANDAXBHBLBPBXBYTECHCLCSCXDHDIDLDSDWORDDXEAXEBPEBXECXEDIEDXEIPESESIESPFSGSHIGHLOWMODNOT OFFSET ORPTRQWORDSHLSHRSISPSS ST TBYTE TYPE WORDXOR非常遺憾, 現在我不能給每個關鍵字做一個哪怕是非常簡單的解釋, 以後會了再補吧.
Time of Update: 2018-12-07
//Delphi 函數function DelphiFun(x: Integer): Integer;begin Result := x * 2;end;//彙編函數, 和上面的函數是同樣的功能function AsmFun(x: Integer): Integer;asm add eax, eax {eax 可以擷取第一個參數, 同時又是函數的傳回值, 所以可以如此簡潔!}end;//測試 DelphiFunprocedure TForm1.Button1Click(Sender:
Time of Update: 2018-12-07
前面知道了一個彙編的賦值指令(MOV), 再瞭解一個加法指令(ADD), 就可以做個例子了.譬如: ADD AX,BX; 這相當於 Delphi 中的 AX := AX + BX;另外提前來個列表 - Delphi 可以用彙編管理以下寄存器:32 位寄存器: EAX EBX ECX EDX ESP EBP ESI EDI16 位寄存器: AX BX CX DX SP BP SI DI8 位寄存器 : AL BL CL DL AH BH CH DH16 位段寄存器: CS DS SS ES
Time of Update: 2018-12-07
CPU 提供了諸多寄存器, 但在 Delphi 的過程和函數中, 只有 EAX ECX EDX 三個寄存器可以自由使用;如果改變了其他寄存器, 在過程和函數結束前要給恢複.記得前面學習過 Delphi 的過程和函數預設的呼叫慣例是 Register , 前三個參數通過寄存器傳遞, 其他參數存與棧.它所指的三個寄存器就應該是 EAX ECX EDX 了.看資料介紹應該是: EAX 先接受第一個參數再接受傳回值, ECX EDX 接受後面兩個參數.但我不能進行完整的測試.//測試三個自由寄存器:
Time of Update: 2018-12-07
//以下三個函數功能一樣, 但效率不同{Fun1 需要讀取常數 0, 最慢}function Fun1: Integer;asm mov eax, 0end;{Fun2 與 Fun3 只是操作 CPU 的寄存器, 比 Fun1 快}function Fun2: Integer;asm sub eax, eaxend;{Fun3 最快}function Fun3: Integer;asm xor eax, eaxend;//速度測試procedure TForm1.Button1Click(
Time of Update: 2018-12-07
//常量可以在彙編語句中運算function Fun: Integer;const a = 11; b = 5;asm mov eax, a-bend;//測試procedure TForm1.Button1Click(Sender: TObject);var i: Integer;begin i := Fun; ShowMessage(IntToStr(i)); {6}end;//變數不可以, 方法中的參數也都屬於變數function Fun: Integer;var x,y:
Time of Update: 2018-12-07
//在彙編中訪問 Delphi 的變數可以使用 & 操作符procedure Proc(str1,str2: string);var s1,s2: string;begin asm mov ecx, &str1 {} mov edx, &str2 mov &s1, ecx {} mov &s2, edx end; ShowMessage(s1 + s2);end;{在沒有歧義的情況下, 操作符 &
Time of Update: 2018-12-07
譬如 EAX AX AH AL 四個儲存器, 真實存在的其實只有一個 EAX, AX AH AL 不過是不同的訪問方式.11111111 11111111 11111111 11111111 : EAX11111111 11111111 11111111 11111111 : AX11111111 11111111 11111111 11111111 : AH11111111 11111111 11111111 11111111 : AL//譬如 AX 是一個16位2位元組儲存器,
Time of Update: 2018-12-07
前面提到 32 位的寄存器有: EAX EBX ECX EDX ESP EBP ESI EDI; 其中, EAX ECX EDX 是自由使用的.那麼剩下的 EBX ESP EBP ESI EDI 五個寄存器就是應該保護的!所謂保護, 並不是不可以使用, 而是在使用前先把其中的值寄存在另外一個地方, 用完後再恢複其值.如果不這樣做, 有可能會發生意想不到的錯誤.舉例://使用應該保護的 ebx 寄存器function Fun(x: Integer): Integer;asm push ebx
Time of Update: 2018-12-07
關於進位:生活中有 7進位(星期)、60進位(小時)、10進位(算術)等等.電腦要用到 10進位、16進位、2進位和 8進位.8進位用得少了, 但也有, 譬如 Unix 伺服器上的檔案屬性.2進位是電腦容易識別的; 10進位是人容易識別的, 據說 10進位源自於人有十個手指.電腦為什麼會使用 8進位和 16進位呢?因為: 23=8; 24=16; 這樣比較容易和 2進位換算.從這裡也能看出, 2進位和 10進位的換算相對複雜些.下面例子中說明了進位的表示方法, 七個函數都會返回整數 255://