Visual Studio汇编字符编码默认规则与识别方法相关问询
汇编场景下字符编码相关问题解答
关于Latin2是否为汇编默认编码的疑问
汇编本身没有内置的默认字符编码,你遇到的Latin2生效的情况,本质是单字节字符的显示层解析属性,和汇编本身无关。
汇编仅会将db指令后定义的字面量、十六进制值原封不动转换为字节存储在数据段中,本身不参与字符编码的逻辑处理。比如你代码里写的0A2H,在Latin2编码规则下会被解析为ą,在Latin1编码规则下就会被解析为¢,最终的展示效果完全由接收这些字节的上层程序(比如你调用的C库write对应的控制台输出模块)的编码解析规则决定。
你对emoji存储的理解是正确的:这类特殊字符确实会占用多字节存储空间,但在汇编层面只会把它当成连续的普通字节处理,只有上层系统使用UTF-8/UTF-16这类多字节编码规则解析时,才会被识别为单个emoji字符。
关于汇编场景下字符编码的判定方法
不需要完全依赖测试数值匹配编码表的兜底方案,你可以按以下优先级从高到低判断编码体系:
- 优先看你调用的系统/库API的编码要求:你当前使用的是32位Windows平台的C库
__write输出到控制台,对应的默认编码和系统的非Unicode程序编码(即ANSI代码页)直接绑定,波兰语区域的Windows默认ANSI代码页就是28592(也就是Latin2),这也是你测试后结果匹配的核心原因。如果你调用的是Windows原生宽字符API例如WriteConsoleW,则固定使用UTF-16LE编码。 - 其次看汇编器的字面量解析规则:如果你在
db指令后直接写非ASCII的字面量,比如db 'ą',汇编器会按照你源代码文件的保存编码将字符转换为对应的字节存储,此时使用的编码和你源码的保存编码完全一致。 - 最后才使用测试匹配的兜底方案:如果前两类信息都缺失,可以输入已知字符的对应编码字节,将输出结果和编码表做匹配反推当前使用的编码,这是通用性最强的判定方式。
示例代码(课堂原始版本)
; program przykładowy (wersja 32-bitowa) .686 .model flat extern _ExitProcess@4 : PROC extern __write : PROC ; (dwa znaki podkreślenia) public _main .data tekst db 10, 'Nazywam sie . . . ' , 10 db 'M',0A2H, 'j pierwszy 32-bitowy program ' db 'asemblerowy dzia', 88H ,'a j',75H,0BEH,' poprawnie!', 10 .code _main PROC mov ecx, 85 ; liczba znaków wyświetlanego tekstu ; wywołanie funkcji ”write” z biblioteki języka C push ecx ; liczba znaków wyświetlanego tekstu push dword PTR OFFSET tekst ; położenie obszaru ; ze znakami push dword PTR 1 ; uchwyt urządzenia wyjściowego call __write ; wyświetlenie znaków ; (dwa znaki podkreślenia _ ) add esp, 12 ; usunięcie parametrów ze stosu ; zakończenie wykonywania programu push dword PTR 0 ; kod powrotu programu call _ExitProcess@4 _main ENDP END
内容的提问来源于stack exchange,提问作者Michał Turek
相关产品推荐
相关产品推荐

