拼命尝试使用 wprintf 在 64 位 NASM x86 程序集中打印 unicode

Posted

技术标签:

【中文标题】拼命尝试使用 wprintf 在 64 位 NASM x86 程序集中打印 unicode【英文标题】:Desperately trying to print unicode in 64 bit NASM x86 assembly with wprintf 【发布时间】:2014-05-06 11:24:52 【问题描述】:

到目前为止,这是我的代码。我已经让它打印了很多问号,它甚至无法识别我格式中的换行符。我希望最终能够增加 unicode 值,以便该函数打印一组大约 50 个 unicode 字符,但我很难让它只打印一个:S

; compile with
; nasm -felf64 Uniwc.asm && gcc Uniwc.o && ./a.out

        global main
        extern wprintf
        section .text
main:

        mov     rdi, fmt
        mov     rsi, uchar
        mov     rax, 0
        call    wprintf
        ret
uchar:
        db '/u0021'
fmt:
        db "%ls",0

编辑:通过确保在打印前对齐堆栈,我得到了类似的代码来打印 UTF-8 字符

; nasm -felf64 Uniwc.asm && gcc Uniwc.o && ./a.out

        global main
        extern printf
        section .text
main:
        push    rbp
        mov     rdi, fmt
        mov     rsi, uchar
        mov     rax, 0
        call    printf
        pop     rbp
        ret
uchar:
        db 0x21, 0

fmt:
        db "%c", 10, 0

现在我遇到了一个新问题,如果我更改 uchar 中的 unicode,例如,如果我将其更改为 0x7E (~),程序将不会返回新字符,它仍然会打印 0x21 (!) 我假设这是堆栈上的 rbp 寄存器有问题,但我不确定如何解决它

【问题讨论】:

【参考方案1】:

您的第一个错误是 /u0021 应该是 \u0021。但是,这对您没有帮助,因为 wprintf 需要 宽字符,在 Linux 上通常是 UTF-32。而 NASM 的 \u 语法会创建 UTF-8 字符串。

目前看来,在 NASM 中,除了使用 dd 指定代码点值数组之外别无他法。例如。类似:

uchar:
      dd '!', 0

第二个问题是您正在使用%ls,它需要一个以零结尾的字符序列,并且您正在传递一个字符。这就是为什么我在上面加了一个零。

第三个问题是格式字符串也应该是宽字符串。试试这个:

fmt:
        dd '%', 'l', 's', 0

【讨论】:

只是想知道,wprintf() 是否真的使用加载到寄存器中的参数,还是应该将所有这些都压入堆栈? 它使用当前系统的任何调用约定。在 Linux x64 上它是 SysV AMD64 ABI,所以它使用 RDI、RSI 等。 感谢并为愚蠢的错误感到抱歉,但对于我正在尝试做的事情,我不能只硬编码值“!”我有一个工作的 nasm 程序可以做到这一点。我特别想做的是从 UTF-16 代码点打印。我会继续摆弄它。【参考方案2】:

正如 Igor 指出的,\u 用于 UTF-8 字符。根据 Nasm 文档,您可以使用 these macros 定义不同类型的 UTF 字符串。您可能必须在 Linux 上使用 UTF-32,在 Windows 上使用 UTF-16。

【讨论】:

以上是关于拼命尝试使用 wprintf 在 64 位 NASM x86 程序集中打印 unicode的主要内容,如果未能解决你的问题,请参考以下文章

在 RHEL 6 x64 中配置网络音频系统 [NAS] 时出错

wprintf: %p 带 NULL 指针

graalvm win10 64位环境搭建

为啥 wprintf 在 Linux 上将 Unicode 中的俄语文本音译成拉丁语?

影视后期专用NAS介绍:支持2台MacOS工作站UHD50P_ProRes4444同时实时回放的8盘位静音万兆NAS

Linux 上的 wprintf UTF16(应该是 UTF8)?