详解汇编中的movzx和movsx指令

1.相关的汇编指令

1.movsx:有符号扩展,就是将扩展后的最高位(符号位),对应SF标志位的内容,填充到扩展的高位部分

2.movzx:无符号扩展就是直接用0去填充扩展的高位部分

2.无符号代码验证

#include"stdio.h"
int main()
{
	unsigned char a = 0xff;
	printf("%d\n", a);
	int b;
	b = a + 1;
	printf("%d\n", b);
	a = a + 1;
	printf("%d\n", a);
	return 0;
}

结果

查看相应的汇编代码

2: int main()
     3: {
00A33E60 55                   push        ebp  
00A33E61 8B EC                mov         ebp,esp  
00A33E63 81 EC D8 00 00 00    sub         esp,0D8h  
00A33E69 53                   push        ebx  
00A33E6A 56                   push        esi  
00A33E6B 57                   push        edi  
00A33E6C 8D 7D E8             lea         edi,[ebp-18h]  
00A33E6F B9 06 00 00 00       mov         ecx,6  
00A33E74 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00A33E79 F3 AB                rep stos    dword ptr es:[edi]  
00A33E7B B9 08 C0 A3 00       mov         ecx,offset _D9388DD4_size@cpp (0A3C008h)  
00A33E80 E8 82 D4 FF FF       call        @__CheckForDebuggerJustMyCode@4 (0A31307h)  
     4: 	unsigned char a = 0xff;
00A33E85 C6 45 FB FF          mov         byte ptr [a],0FFh  
     5: 	printf("%d\n", a);
00A33E89 0F B6 45 FB          movzx       eax,byte ptr [a]  
00A33E8D 50                   push        eax  
00A33E8E 68 CC 7B A3 00       push        offset string "%d\n" (0A37BCCh)  
00A33E93 E8 0A D5 FF FF       call        _printf (0A313A2h)  
00A33E98 83 C4 08             add         esp,8  
     6: 	int b;
     7: 	b = a + 1;
00A33E9B 0F B6 45 FB          movzx       eax,byte ptr [a]  
00A33E9F 83 C0 01             add         eax,1  
00A33EA2 89 45 EC             mov         dword ptr [b],eax  
     8: 	printf("%d\n", b);
00A33EA5 8B 45 EC             mov         eax,dword ptr [b]  
00A33EA8 50                   push        eax  
00A33EA9 68 CC 7B A3 00       push        offset string "%d\n" (0A37BCCh)  
00A33EAE E8 EF D4 FF FF       call        _printf (0A313A2h)  
00A33EB3 83 C4 08             add         esp,8  
     9: 	a = a + 1;
00A33EB6 0F B6 45 FB          movzx       eax,byte ptr [a]  
00A33EBA 83 C0 01             add         eax,1  
00A33EBD 88 45 FB             mov         byte ptr [a],al  
    10: 	printf("%d\n", a);
00A33EC0 0F B6 45 FB          movzx       eax,byte ptr [a]  
00A33EC4 50                   push        eax  
00A33EC5 68 CC 7B A3 00       push        offset string "%d\n" (0A37BCCh)  
00A33ECA E8 D3 D4 FF FF       call        _printf (0A313A2h)  
00A33ECF 83 C4 08             add         esp,8  
    11: 	return 0;
00A33ED2 33 C0                xor         eax,eax  
    12: }

a.最初的char类型的变量的长度是byte

b.类型转换中char类型向int类型转换

使用到了movzx指令,实现了无符号扩展,此时eax中的值为 0x00ff

随后加一,并将eax中的值 0x0100 赋给b,

所以最终b值为256

c.char 类型的无符号溢出

同样的先使用movzx进行无符号扩展

不过与b不同的点在于,将al寄存其中的值赋给了a,也就是0x0100的后两位 00

所以最后a 的值为0

3.有符号代码验证

#include"stdio.h"
int main()
{
	char a = 0xff;
	printf("%d\n", a);
	int b;
	b = a + 1;
	printf("%d\n", b);
	a = a + 1;
	printf("%d\n", a);
	return 0;
}

代码

汇编代码

  2: int main()
     3: {
00983E60 55                   push        ebp  
00983E61 8B EC                mov         ebp,esp  
00983E63 81 EC D8 00 00 00    sub         esp,0D8h  
00983E69 53                   push        ebx  
00983E6A 56                   push        esi  
00983E6B 57                   push        edi  
00983E6C 8D 7D E8             lea         edi,[ebp-18h]  
00983E6F B9 06 00 00 00       mov         ecx,6  
00983E74 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00983E79 F3 AB                rep stos    dword ptr es:[edi]  
00983E7B B9 08 C0 98 00       mov         ecx,offset _D9388DD4_size@cpp (098C008h)  
00983E80 E8 82 D4 FF FF       call        @__CheckForDebuggerJustMyCode@4 (0981307h)  
     4: 	char a = 0xff;
00983E85 C6 45 FB FF          mov         byte ptr [a],0FFh  
     5: 	printf("%d\n", a);
00983E89 0F BE 45 FB          movsx       eax,byte ptr [a]  
00983E8D 50                   push        eax  
00983E8E 68 CC 7B 98 00       push        offset string "%d\n" (0987BCCh)  
00983E93 E8 0A D5 FF FF       call        _printf (09813A2h)  
00983E98 83 C4 08             add         esp,8  
     6: 	int b;
     7: 	b = a + 1;
00983E9B 0F BE 45 FB          movsx       eax,byte ptr [a]  
00983E9F 83 C0 01             add         eax,1  
00983EA2 89 45 EC             mov         dword ptr [b],eax  
     8: 	printf("%d\n", b);
00983EA5 8B 45 EC             mov         eax,dword ptr [b]  
00983EA8 50                   push        eax  
00983EA9 68 CC 7B 98 00       push        offset string "%d\n" (0987BCCh)  
00983EAE E8 EF D4 FF FF       call        _printf (09813A2h)  
00983EB3 83 C4 08             add         esp,8  
     9: 	a = a + 1;
00983EB6 0F BE 45 FB          movsx       eax,byte ptr [a]  
00983EBA 83 C0 01             add         eax,1  
00983EBD 88 45 FB             mov         byte ptr [a],al  
    10: 	printf("%d\n", a);
00983EC0 0F BE 45 FB          movsx       eax,byte ptr [a]  
00983EC4 50                   push        eax  
00983EC5 68 CC 7B 98 00       push        offset string "%d\n" (0987BCCh)  
00983ECA E8 D3 D4 FF FF       call        _printf (09813A2h)  
00983ECF 83 C4 08             add         esp,8  
    11: 	return 0;
00983ED2 33 C0                xor         eax,eax  
    12: }

此处char型变量a中值最初是0xff,此时的符号位为1

使用movsx指令进行有符号扩展后将值存入eax中,eax中保存的值为0xffff

eax加1之后,发生溢出,此时eax中保存的值为0x0000

所以最终b中的值为0

此处同理,在eax进行带符号扩建并加1操作之后,eax值为0x0000,此时的al中的值为0x00.

所以最终a 中的值为0

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tntlbb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值