You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下FASM西里尔字母转大写函数处理俄语字母失效问题

解决UTF-8俄语字母转大写的FASM通用方案

你的代码失效的核心问题是直接对UTF-8编码的字节值做比较和加减——俄语字母的UTF-8大小写编码并非统一差0x20(比如ё的大小写编码差就不是0x20),而且原有的范围判断逻辑完全错误,因为UTF-8编码的大小写值并不落在你设定的区间里。

正确的思路是绕开直接操作UTF-8字节,先把双字节UTF-8解码成Unicode码点,完成大写转换后再重新编码回UTF-8,这样就能通用处理所有俄语字母。

原代码的具体问题

  1. 范围判断逻辑错误:你拿я的UTF-8编码(0xD18F)和Я的UTF-8编码(0xD0AF)做区间判断,但这两个值本身就不是连续区间的边界,导致大部分俄语小写字母都被错误跳过。
  2. 直接对UTF-8字节减0x20:只有部分俄语字母的UTF-8大小写编码差是0x20,像ё这种特殊字母完全不适用,无法覆盖所有情况。

通用解决步骤

  1. 解码UTF-8到Unicode码点:双字节UTF-8的格式是110xxxxx 10yyyyyy,解码成Unicode码点的公式是:
    码点 = ((第一个字节 & 0x1F) << 6) | (第二个字节 & 0x3F)
    
  2. Unicode码点转大写:
    • 俄语小写字母的码点范围是U+0430到U+044F,对应大写码点是U+0410到U+042F,直接减0x20即可。
    • 特殊字母ё的码点是U+0451,对应大写Ё的码点是U+0401,单独处理。
  3. 编码回UTF-8双字节:如果码点在U+0080到U+07FF之间(所有俄语字母都在此区间),编码公式是:
    第一个字节 = 0xC0 | (码点 >> 6)
    第二个字节 = 0x80 | (码点 & 0x3F)
    

修改后的FASM代码

; 前提:AX中存储双字节UTF-8字符(ah=第一个字节,al=第二个字节)
; 第一步:解码UTF-8到Unicode码点,存入BX
mov bx, ah         ; 取UTF-8第一个字节
and bx, 0x1F       ; 保留低5位(对应格式中的xxxxx)
shl bx, 6          ; 左移6位,为第二个字节的低6位腾位置
mov cx, al         ; 取UTF-8第二个字节
and cx, 0x3F       ; 保留低6位(对应格式中的yyyyyy)
or bx, cx          ; 合并得到完整的Unicode码点

; 第二步:判断是否需要转大写
cmp bx, 0x0430     ; 俄语小写字母的起始码点(а)
jb skip_convert    ; 小于则不是俄语小写,跳过转换
cmp bx, 0x044F     ; 俄语小写字母的结束码点(я)
ja check_yo        ; 大于则检查是否是ё

; 普通俄语小写字母,直接转大写
sub bx, 0x20
jmp encode_back

check_yo:
cmp bx, 0x0451     ; 检查是否是ё的码点
jne skip_convert
mov bx, 0x0401     ; 转成Ё的码点
jmp encode_back

skip_convert:
; 不需要转换,直接用原AX的UTF-8值
jmp write_output

encode_back:
; 第三步:将Unicode码点重新编码为双字节UTF-8
mov ax, bx
shr ax, 6          ; 取码点的高5位
or ah, 0xC0        ; 设置UTF-8第一个字节的前缀110
mov al, bx
and al, 0x3F       ; 取码点的低6位
or al, 0x80        ; 设置UTF-8第二个字节的前缀10
; 现在AX中就是转换后的UTF-8双字节(ah=第一个字节,al=第二个字节)

write_output:
; 写入结果到RDI指向的内存(x86是小端序,必须按UTF-8顺序存ah和al)
mov byte [rdi], ah
mov byte [rdi+1], al
add rdi, 2
jmp loop_string

关键说明

  • 你之前mov word [rdi], ax失效的原因:x86是小端字节序,这条指令会先把al存入[rdi],再把ah存入[rdi+1],但UTF-8需要按原字节顺序(第一个字节在前)存储,所以必须分开写入ah和al。
  • 这个方案通过Unicode码点处理,能覆盖所有俄语字母的大小写转换,不用再逐个字符写判断逻辑。

内容的提问来源于stack exchange,提问作者Alexandr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:50:22