0

ここで初めてのSOユーザー。

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  

_MBCS が定義されている場合にのみ _mbslen が使用されるとドキュメントに記載されている場合、_tcslen(streng)が への呼び出しにコンパイルされる理由がわかりません。_mbslen

でコンパイルしcl -Zi main.cdevenv main.exe_UNICODE も _MBCS も定義されていないことを確認できたらUINT cs = UC | UM;(cs は 0xa です)。

UNICODE を定義する最初の行を削除し、コマンド プロンプトでコードページを 65001 に設定すると、ソース ファイルを utf-8 で保存するため、すべて正常に動作します。また、UNICODE 定義を保持しているwcslen(streng)が、文字列内のハードコードとコード ポイントも機能します。これにより、たとえ _tcslen が wcslen になったとしても、Unicode コード ポイントを文字列にハードコードしない限り機能しないと思われます。しかし、それは本当のポイントではありません。コンパイラが wcslen ではなく _mbslen を呼び出す理由を知りたいです。

4

0 に答える 0