assemblyx86x86-64nasmfasm

Unable to print Unicode string using wprintf in FASM or NASM


I'm having trouble printing a Unicode string using the wprintf function in FASM (Flat Assembler).

I've tried the following code, but it produces random output (हिन्ि):


format PE64 console
entry start

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

;======================================
section '.data' data readable writeable
;======================================
;unicode for हिन्दी
wunicode_string dw  0xe0, 0xa4, 0xb9, 0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xa8, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xbf



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

start:
    
    mov rax, 0
    ccall [wprintf], "%ls", wunicode_string
   

    ccall   [getchar]                   ; I added this line to exit the application AFTER the user pressed any key.
    stdcall [ExitProcess],0             ; Exit the application

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

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

import  kernel,        ExitProcess,'ExitProcess'

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


Solution

  • It shows correct output if we set correct code page for the console which we can do in FASM (will work in NASM too) like below:

    format PE64 console
    entry start
    
    include './include/win64a.inc'
    include './include/macro/proc64.inc'
    
    
    ;=======================================
    section '.code' code readable executable
    ;=======================================
    
    start:
    
        ccall   [SetConsoleOutputCP], 65001
        ccall   [printf], "%s", "हिन्दी"
    
    
        ccall   [getchar]                   ; I added this line to exit the application AFTER the user pressed any key.
        stdcall [ExitProcess], 0            ; Exit the application
    
    ;====================================
    section '.idata' import data readable
    ;====================================
    
    library kernel,'kernel32.dll',\  
            msvcrt,'msvcrt.dll'
    
    import  kernel,\  
            ExitProcess,'ExitProcess',\  
            SetConsoleOutputCP, 'SetConsoleOutputCP'
    
    import  msvcrt,\  
            printf,'printf',\  
            getchar,'_fgetchar'
    

    I've used printf but it will work for wprintf too.