|  | 
          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);
 只不過括號比較多而已。
 
 |