fc2ブログ

lltoa(インラインアセンブラ版)

64ビット符号付き整数(LONGLONG)を文字列に変換する関数。
無駄にアセンブラで実装。
必要に駆られて作ったけど要らなくなってしまい消すのも勿体無いのでメモ。
速度よりサイズ重視。まだ改良の余地はありげ。
# バッファに反転コピー辺りはストリング命令使えばもっと良くなるはず

肝は負数は反転して正数にしてしまうのと64bit整数の割り算で商が32bitを超える場合の対処法で、最初に上位32bitを割っておいてその商を別に保存し、余りを上位32bitに設定しなおして再度割ってやるとオーバーフローせずに32bitに収まり、別に保存した上位32bitと計算結果の商の下位32bitで64bitの商が弾き出せます。

というわけで以下コード。

void lltoa(LONGLONG value, char *string)
{
char tmp[20];
_asm {
; edi データ保存
; esi 割る数(10)
; ecx:ebx value
// 絶対値取得
lea edi, tmp
mov esi, 10
mov ecx, dword ptr[value+4]
mov ebx, dword ptr[value]
or ecx, ecx
jge LTA1
mov eax, ecx
mov edx, ebx
neg eax
neg edx
sbb eax, 0
mov ecx, eax
mov ebx, edx
mov eax, string
mov [eax], '-'
inc string
// 商余Get
LTA1: mov eax, ecx
xor edx, edx
div esi
mov ecx, eax ; 商上位32bit
mov eax, ebx
div esi
mov ebx, eax ; 商下位32bit
add edx, '0' ; 余
mov [edi], dl
inc edi
test ecx,ecx
jne LTA1
test ebx,ebx
jne LTA1
// バッファに反転コピー
lea ebx, tmp
mov esi, string
LTA2: dec edi
mov al, [edi]
mov [esi], al
inc esi
cmp edi, ebx
jne LTA2
mov [esi], 0
}
}

コメントの投稿

非公開コメント

月別アーカイブ
カテゴリー
リンク
ブログ内検索
RSSフィード