“这编译器真好,速度特别快!”

分享一则编译器的趣事,内容取自【日】川合秀实的《30天自制操作系统》

unsigned int memtest_sub(unsigned int start, unsigned int end)
{
    unsigned int i, *p, old, pat0 = 0xaa55aa55, pat1 = 0x55aa55aa;
    for (i = start; i <= end; i += 4) {
        p = (unsigned int *) i;
        old = *p; 			/* 先记住修改前的值 */
        *p = pat0; 			/* 试写 */
        *p ^= 0xffffffff; 	/* 反转 */
        if (*p != pat1) { 	/* 检查反转结果 */
not_memory:
            *p = old;
            break;
        }
        *p ^= 0xffffffff; 	/* 再次反转 */
        if (*p != pat0) { 	/* 检查值是否恢复 */
            goto not_memory;
        }
        *p = old; 			/* 恢复为修改前的值 */
    }
    return i;
} 

​ 这个程序所做的是:调查从start地址到end地址的范围内,能够使用的内存的末尾地址。要做 的事情很简单。首先如果p不是指针,就不能指定地址去读取内存,所以先执行“p=i;”。紧接着 使用这个p,将原值保存下来(变量old)。接着试写0xaa55aa55,在内存里反转该值,检查结果是 否正确①。如果正确,就再次反转它,检查一下是否能回复到初始值。最后,使用old变量,将内 存的值恢复回去。……如果在某个环节没能恢复成预想的值,那么就在那个环节终止调查,并报 告终止时的地址。

​ 以上程序是笔者对0x00400000~0xbfffffff范围的内存进行检查,关于反转,笔者用XOR运算来实现,其运算符是“”。“*p = 0xffffffff;”是“*p = *p^0xffffffff;” 的省略形式。

然后就出问题了,笔者描述很清晰,就截图吧:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

哈哈哈哈!!用户肯定会说:“这编译器真好,速度特别快!”


这个故事告诉我们汇编真的很重要,笔者用汇编语言改写的程序如下:
_memtest_sub: 	; unsigned int memtest_sub(unsigned int start, unsigned int end)
     PUSH 		EDI 					; (由于还要使用EBX, ESI, EDI)
     PUSH 		ESI
     PUSH 		EBX
     MOV 		ESI,0xaa55aa55 			; pat0 = 0xaa55aa55;
     MOV 		EDI,0x55aa55aa 			; pat1 = 0x55aa55aa;
     MOV 		EAX,[ESP+12+4] 			; i = start;
mts_loop:
     MOV 		EBX,EAX
     ADD 		EBX,0xffc 				; p = i + 0xffc;
     MOV 		EDX,[EBX] 				; old = *p;
     MOV 		[EBX],ESI 				; *p = pat0;
     XOR 		DWORD [EBX],0xffffffff 	; *p ^= 0xffffffff;
     CMP 		EDI,[EBX] 				; if (*p != pat1) goto fin;
     JNE 		mts_fin
     XOR 		DWORD [EBX],0xffffffff 	; *p ^= 0xffffffff;
     CMP 		ESI,[EBX] 				; if (*p != pat0) goto fin;
     JNE 		mts_fin
     MOV 		[EBX],EDX 				; *p = old;
     ADD 		EAX,0x1000 				; i += 0x1000;
     CMP 		EAX,[ESP+12+8] 			; if (i <= end) goto mts_loop;
     
     JBE  		mts_loop
     POP 		EBX
     POP 		ESI
     POP 		EDI
     RET
mts_fin:
     MOV [EBX],EDX 						; *p = old;
     POP EBX
     POP ESI
     POP EDI
     RET
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值