在x86汇编中如何通过C函数将读取的无符号字节转为有符号整数?
解决fread读取二进制字节作为有符号整数的问题
首先明确:fread只是原封不动地把二进制字节从文件读入内存,它根本不会做“无符号/有符号”的解析——数据本身就是0xCA,调试器显示202只是因为它默认按无符号字节来显示,而非数据本身有问题。
你用sscanf的方法完全走错了方向:sscanf是用来解析ASCII字符串的,比如把字符串"202"或者"-5"转成整数,但你给它的是二进制值0xCA(对应ASCII的Ê字符),它根本无法匹配%hhi格式,所以返回0表示匹配失败,自然不会修改numberInt的值。
正确的解决方法:直接做符号扩展
x86架构提供了专门的符号扩展指令,能把8位有符号字节转换成32位/64位有符号整数,核心是movsx指令(move with sign extension):
读取字节后,执行以下代码即可得到正确的有符号值:
; 假设number是8位变量,numberInt是32位有符号整数变量 mov al, [number] ; 将读取到的字节加载到al寄存器(8位) movsx eax, al ; 符号扩展到32位,eax中就是正确的有符号值 mov [numberInt], eax ; 保存到目标变量
如果需要64位的有符号整数,就用:
mov al, [number] movsx rax, al mov [numberInt64], rax
这个方法的原理是:有符号字节的最高位(第7位)是符号位,movsx会把这个位复制到所有更高的位,比如0xCA(二进制11001010,最高位为1)扩展到32位就是0xFFFFFFCA,对应的十进制就是-5,完全符合你的需求。
额外说明
- 不需要依赖任何标准库函数,直接用CPU指令就能完成,效率更高
- 调试器显示值的时候,可以手动切换显示格式为“有符号字节”,就能直接看到-5这类结果,不需要先转换
内容的提问来源于stack exchange,提问作者CrazyBrocoli
相关产品推荐
相关产品推荐

