|
12樓 巨大八爪鱼
2016-2-26 14:43
彙編語言中的除法指令: 【彙編部分】 GLOBAL div div: MOV AX, [ESP+4] DIV BYTE[ESP+8] RET 【C語言部分】 #include <stdio.h> short div(unsigned char a, unsigned char b); int main() { short num = div(10, 3); printf("%d ... %d\n", num & 0xff, num >> 8); return 0; } 運行結果: 3 ... 1
|
|
13樓 巨大八爪鱼
2016-2-26 15:22
在彙編語言中調用C語言函數: 【彙編部分】 GLOBAL fun fun: CALL [ESP+4] RET 【C語言部分】 #include <stdio.h> void fun(void (*f)()); void test() { printf("This is a string.\n"); } int main() { fun(test); return 0; } 輸出: This is a string.
|
|
14樓 巨大八爪鱼
2016-2-26 16:14
彙編語言創建C語言可寫的數組的方法: 【彙編部分】 SECTION .bss GLOBAL arr arr: RESB 20 【C語言部分】 #include <stdio.h> #include <string.h> extern char arr[20]; int main() { strcpy(arr, "This is a string."); puts(arr); return 0; }
輸出: This is a string.
|
|
15樓 巨大八爪鱼
2016-2-26 16:27
關於彙編語言中的三個段: 【彙編部分】 ; BSS段中專門存放未初始化的變數 SECTION .bss GLOBAL arr arr: RESB 20
; 這個段中不可以定義函數 ;fun3: ; RET
; DATA段中專門存放已初始化的變數 ; 其中的內容可讀可寫 SECTION .data GLOBAL msg msg: DB "Hello, World!" DB 0
GLOBAL fun2 fun2: RET
; TEXT段中的內容是只讀的 SECTION .text GLOBAL str GLOBAL fun str: DB "abcdef" DB 0 fun: MOV EAX, 14 RET 【C語言部分】 #include <stdio.h> #include <string.h> extern char arr[20]; extern char msg[]; extern char str[]; int fun(); void fun2(); int main() { strcpy(arr, "This is a string."); puts(arr); msg[0] = 'I'; puts(msg); printf("%d\n", fun()); //str[0] = 'm'; // 只讀!將會引發段錯誤 puts(str); fun2(); return 0; } 【輸出】 This is a string. Iello, World! 14 abcdef
|
|
16樓 巨大八爪鱼
2016-2-26 16:41
接下來我們來一點刺激的! 把一個C語言數組拿來執行!
【C語言部分】 #include <stdio.h> #include <string.h>
extern char fun, end; // fun函數的開始和結束位置 char codes[200];
int main() { int size = &end - &fun; // fun函數的機器代碼大小 printf("size=%d\n", size); memcpy(codes, &fun, size); // 把fun函數的機器代碼複製到codes數組中 // 執行codes數組中所存放的機器代碼,並讀取代碼執行完畢後EAX暫存器中的值 int (*fun)() = (int (*)())codes; int v = fun(); printf("%d\n", v); return 0; } 【彙編部分】 GLOBAL fun GLOBAL end fun: MOV EAX, 48 RET end:
【運行結果】 size=6 48
|
|
17樓 巨大八爪鱼
2016-2-26 16:43
int (*fun)() = (int (*)())codes; 這句話的意思就是:先定義一個fun變數,變數的類型為函數指針。 然後把codes變數(本來是一個數組)強行轉換成函數指針,賦給fun變數。
|
|
18樓 巨大八爪鱼
2016-2-26 16:48
16樓所示的代碼有點沒寫好,因為main函數中有兩個fun,所以乾脆改一個名字吧,更容易理解: #include <stdio.h> #include <string.h>
extern char fun, end; // fun函數的開始和結束位置 char codes[200];
int main() { int (*fff)(); // 定義一個函數指針 int v; int size = &end - &fun; // fun函數的機器代碼大小 printf("size=%d\n", size); memcpy(codes, &fun, size); // 把fun函數的機器代碼複製到codes數組中 // 執行codes數組中所存放的機器代碼,並讀取代碼執行完畢後EAX暫存器中的值 fff = (int (*)())codes; v = fff(); printf("%d\n", v); return 0; }
|
|
19樓 巨大八爪鱼
2016-2-26 16:55
實際上,不需要定義函數指針,就能直接執行codes數組: v = ((int (*)())codes)(); printf("%d\n", v); 只不過括號比較多而已。
|