You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在FASM/NASM中使用wprintf打印Unicode字符串失败的问题

解决FASM中wprintf打印Unicode字符串乱码的问题

问题根源

你的代码存在两个核心错误:

  1. 编码格式不匹配:你把印地语"हिन्दी"的UTF-8字节序列用dw(16位字)存储,但wprintf的%ls参数要求输入UTF-16LE编码的宽字符串(Windows原生宽字符格式,每个字符占2字节)。当前写法相当于把每个UTF-8字节单独作为16位字,完全不符合宽字符串的规范。
  2. 控制台编码不支持:Windows控制台默认代码页通常是系统本地编码(如GBK),无法直接渲染Unicode字符,需要切换到支持的编码格式。

修正后的代码

format PE64 console
entry start

include './include/win64w.inc'
include './include/macro/proc64.inc'

;======================================
section '.data' data readable writeable
;======================================
; 印地语"हिन्दी"的UTF-16LE编码,对应码点:U+0939, U+093F, U+0928, U+094D, U+093F
wunicode_string dw 0x0939, 0x093F, 0x0928, 0x094D, 0x093F, 0x0000 ; 宽字符串必须以空字符结尾

;=======================================
section '.code' code readable executable
;=======================================

start:
    ; 设置控制台输出代码页为UTF-8,确保能显示Unicode字符
    mov rcx, 65001
    call [SetConsoleOutputCP]

    ; 调用wprintf打印宽字符串
    mov rax, 0
    ccall [wprintf], "%ls", wunicode_string
   
    ccall [getchar]
    stdcall [ExitProcess], 0

;====================================
section '.idata' import data readable
;====================================

library kernel,'kernel32.dll', msvcrt,'msvcrt.dll'

import kernel, ExitProcess,'ExitProcess', SetConsoleOutputCP,'SetConsoleOutputCP'

import msvcrt, printf,'printf', wprintf, 'wprintf', getchar,'_fgetchar'

关键修正说明

  • 字符串编码修正:将原UTF-8字节序列替换为对应字符的UTF-16LE编码(每个Unicode码点拆分为小端序的16位字),且宽字符串必须以0x0000结尾,wprintf才能正确识别。
  • 控制台编码设置:直接调用Windows API的SetConsoleOutputCP函数,将控制台输出代码页设置为65001(UTF-8),避免依赖外部命令。
  • API导入补充:新增SetConsoleOutputCP函数的导入,用于修改控制台编码。

内容的提问来源于stack exchange,提问作者Shikhar Mishra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 05:27:24