• UTF8转换UTF16(Unicode) 汇编实现


      1 DWORD UTF8ToUnicode(LPVOID utf8Bytes,DWORD bytesLength,LPVOID *unicodeBytes)
      2 {
      3     DWORD charsCount=0;
      4     DWORD result;
      5     LPDWORD pResult=&result;
      6     LPVOID tmpBuffer=NULL;
      7     LPBYTE tmpData=(LPBYTE)utf8Bytes;
      8     if(IsUTF8Data(tmpData))
      9     {
     10         utf8Bytes=tmpData+3;
     11         bytesLength-=3;
     12     }
     13     *unicodeBytes=malloc(bytesLength*2);//分配最大可能需要的内存
     14     //EAX:需要计算的数据
     15     //EBX:操作状态
     16     //ECX:最大源地址
     17     //EDX:计算结果
     18     //ESI:源
     19     //EDI:目标
     20     __asm
     21     {
     22         //push eax;                //对使用到的寄存器进行保存
     23         //push ebx;                //对使用到的寄存器进行保存
     24         //push ecx;
     25         //push edx;
     26         //push esi;
     27         //push edi;
     28         pushad;
     29         MOV eax,0;                
     30         mov esi,utf8Bytes;            //设置源地址
     31         mov edi,DWORD PTR[unicodeBytes];            //设置目标地址
     32         mov edi,DWORD PTR[EDI];
     33         mov ecx,bytesLength;    
     34         add ecx,esi;            //计算源数据最高地址
     35         MOV EBX,pResult
     36             XOR EAX,EAX;
     37         XOR EDX,EDX;
     38 LoopStart:;
     39         mov EAX,DWORD PTR[ESI];//读取数据
     40 
     41         test al,0x80;
     42         jz L1;
     43         test al,0x40;
     44         JZ LoopEnd;            //错误数据
     45         TEST AL,0x20;
     46         JZ    L2;
     47         JNZ L3;
     48 
     49         NOT EBX;     //遇到无效字符(不支持四字节字符)
     50         JMP    LoopEnd;
     51 L3:;
     52         AND EAX,0x003F3F0F;
     53         ADD DL,AL;
     54         SHL EDX,6;
     55         SHR EAX,8;
     56         ADD DL,AL;
     57         SHL EDX,6;
     58         //SHR EAX,8;
     59         ADD DL,AH;
     60         ADD ESI,3;
     61         JMP END;
     62 L2:;
     63         AND EAX,0x00003F1F;
     64         ADD DL,AL;
     65         SHL EDX,6;
     66         //SHR EAX,8;
     67         ADD DL,AH;
     68         ADD ESI,2;
     69         JMP END;
     70 L1:;
     71         MOV DL,AL;
     72         ADD ESI,1;
     73         //SHL EDX,8;
     74 END:;
     75         MOV WORD PTR [EDI],DX;
     76         XOR EDX,EDX;
     77         ADD EDI,2;
     78 
     79         CMP ESI,ECX;
     80         JNGE LoopStart;//如果ESI小于ECX 继续循环
     81 
     82         MOV WORD PTR [EDI],0;
     83         MOV DWORD PTR[EBX],EDI;
     84 LoopEnd:;
     85         //错误的数据
     86         popad
     87             //pop edi;    //恢复使用到的寄存器
     88             //pop esi;
     89             //pop edx;
     90             //pop ecx;
     91             //pop ebx;
     92             //pop eax;
     93     }
     94     if(result!=-1)
     95     {
     96         charsCount=result-(DWORD)*unicodeBytes;
     97         tmpBuffer=malloc(charsCount+4);
     98         memset(tmpBuffer,0,charsCount+4);
     99         memcpy(tmpBuffer,*unicodeBytes,charsCount);
    100         free(*unicodeBytes);
    101         *unicodeBytes=tmpBuffer;
    102     }
    103     return charsCount;
    104 }

    UTF-8编码转换Utf-16

    以上代码不转换4字节Utf-8编码字符,因为4字节Utf-8编码字符无法在UTF-16保存,最大0X1FFFF而Utf-16最大0xFFFF;utf-32可以保存

    Utf-16编码和Unicode是一一对应的,Unicode程序中使用的也就是utf-16;

    所以很多时候需要进行转换,utf-8保存英文字符占用空间小于utf-16,但是对于中文大于utf-16占用的空间

    首先一次性取4个字节(对于32位机器取一个字节的消耗和4个字节一样),然后判断第一个字节(因为使用了寄存器,那么第一个字节就在最低位,低位低字节,高位高字节),

    8 7 6 5 4

    0 x x x x 单字节

    1 1 0 x x 双字节

    1 1 1 0 x 三字节

    1 1 1 1 0四字节

    1 0 x x x多字节的话处第一个字节外其余字节以这个开头

    低位低字节,高位高字节。Unicode有两种表示一种高位在前,另外1种高位在后

    11011111,10001111

    那么结果是11001111,00001111//部分编码选择这种方式

    那么结果是00001111,11001111//目前大多数是这样的

    其实就是高低字节顺序的问题

    更多信息请参见Utf-8编码的标准文档

    上边代码对四字节处理基本忽略掉了,因为出现4字节Utf-16无法保存,所以处理也是白处理

  • 相关阅读:
    linux学习笔记(十四)
    linux学习笔记(十三)
    linux学习笔记(十二)
    linux学习笔记(十一)
    linux学习笔记(十)
    linux学习笔记(九)
    linux学习笔记(八)
    linux学习笔记(七)
    linux学习笔记(六)
    linux学习笔记(五)
  • 原文地址:https://www.cnblogs.com/a185771876/p/2307150.html
Copyright © 2020-2023  润新知