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