0

第一次在这里的用户。

我试图更好地理解 Unicode、utf-8 等。目前我正在从 Windows 命令提示符处执行此操作。

可以发布在 Visual Studio 中看到的反汇编转储吗?

#define UNICODE
#include <windows.h>

#ifdef _UNICODE
UC = 0x1;
#else
UC = 0x2;
#endif

#ifdef _MBCS
UM = 0x4;
#else
UM = 0x8;
#endif

int main()
{
00007FF65B276270 40 56                push        rsi  
00007FF65B276272 57                   push        rdi  
00007FF65B276273 48 83 EC 78          sub         rsp,78h  
00007FF65B276277 48 8B 05 B2 2D 01 00 mov         rax,qword ptr [__security_cookie (07FF65B289030h)]  
00007FF65B27627E 48 33 C4             xor         rax,rsp  
00007FF65B276281 48 89 44 24 68       mov         qword ptr [rsp+68h],rax  
    UINT cs = UC | UM;
00007FF65B276286 8B 05 78 43 01 00    mov         eax,dword ptr [UM (07FF65B28A604h)]  
00007FF65B27628C 8B 0D 6E 43 01 00    mov         ecx,dword ptr [UC (07FF65B28A600h)]  
00007FF65B276292 0B C8                or          ecx,eax  
00007FF65B276294 8B C1                mov         eax,ecx  
00007FF65B276296 89 44 24 38          mov         dword ptr [cs],eax  
    TCHAR streng[] = TEXT("aæbøcådÆeØfÅg");
00007FF65B27629A 48 8D 44 24 40       lea         rax,[streng]  
00007FF65B27629F 48 8D 0D 62 43 01 00 lea         rcx,[UM+4h (07FF65B28A608h)]  
00007FF65B2762A6 48 8B F8             mov         rdi,rax  
00007FF65B2762A9 48 8B F1             mov         rsi,rcx  
00007FF65B2762AC B9 28 00 00 00       mov         ecx,28h  
00007FF65B2762B1 F3 A4                rep movs    byte ptr [rdi],byte ptr [rsi]  
    HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
00007FF65B2762B3 B9 F5 FF FF FF       mov         ecx,0FFFFFFF5h  
00007FF65B2762B8 FF 15 42 9D 01 00    call        qword ptr [__imp_GetStdHandle (07FF65B290000h)]  
00007FF65B2762BE 48 89 44 24 30       mov         qword ptr [hConsoleOutput],rax  
    WriteConsole(hConsoleOutput, streng, _tcslen(streng), 0, 0);
00007FF65B2762C3 48 8D 4C 24 40       lea         rcx,[streng]  
00007FF65B2762C8 E8 6F B1 FE FF       call        _mbslen (07FF65B26143Ch)  
00007FF65B2762CD 48 C7 44 24 20 00 00 00 00 mov         qword ptr [rsp+20h],0  
00007FF65B2762D6 45 33 C9             xor         r9d,r9d  
00007FF65B2762D9 44 8B C0             mov         r8d,eax  
00007FF65B2762DC 48 8D 54 24 40       lea         rdx,[streng]  
00007FF65B2762E1 48 8B 4C 24 30       mov         rcx,qword ptr [hConsoleOutput]  
00007FF65B2762E6 FF 15 1C 9D 01 00    call        qword ptr [__imp_WriteConsoleW (07FF65B290008h)]  
    return 0;
00007FF65B2762EC 33 C0                xor         eax,eax  
}
00007FF65B2762EE 48 8B 4C 24 68       mov         rcx,qword ptr [rsp+68h]  
00007FF65B2762F3 48 33 CC             xor         rcx,rsp  
00007FF65B2762F6 E8 55 AE FE FF       call        __security_check_cookie (07FF65B261150h)  
00007FF65B2762FB 48 83 C4 78          add         rsp,78h  
00007FF65B2762FF 5F                   pop         rdi  
00007FF65B276300 5E                   pop         rsi  
00007FF65B276301 C3                   ret  

文档声明 _mbslen 仅在定义 _MBCS 时使用时,我无法弄清楚为什么_tcslen(streng)编译成调用。_mbslen

我编译cl -Zi main.c时,devenv main.exe我可以确认_UNICODE 和_MBCS 都不是用该行定义的UINT cs = UC | UM;(cs 是0xa)。

如果我删除定义 UNICODE 的第一行并将命令提示符中的代码页设置为 65001,则一切正常,因为我使用 utf-8 保存源文件。如果我wcslen(streng)在字符串中保留 UNICODE 定义但硬编码和代码点,它也可以工作。这让我相信,即使 _tcslen 变成 wcslen 它也不会起作用,除非我将 Unicode 代码点硬编码到字符串中。但这不是重点。我想知道为什么编译器选择调用_mbslen而不是wcslen。

4

0 回答 0