|   | 
              
                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);
 只不过括号比较多而已。
 
 |