0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

備忘録: SHIFT JIS の領域

Posted at

JIS X 0208 の領域と SHIFT JIS の領域の比較

JIS X 0208 の領域

  2121 ... 215F, 2160 ... 217E, 2221 ... 227E
   ...                                   ...
  5D21 ... 5D5F, 5D60 ... 5D7E, 5E21 ... 5E7E
  5F21 ... 5F5F, 5F60 ... 5F7E, 6021 ... 607E
   ...                                   ...
  7D21 ... 7D5F, 7D60 ... 7D7E, 7E21 ... 7E7E

SHIFT JIS の領域

  8140 ... 817E, 8180 ... 819E, 819F ... 81FC
   ...                                   ...
  9F40 ... 9F7E, 9F80 ... 9F9E, 9F9F ... 9FFC
  E040 ... E07E, E080 ... E09E, E09F ... E0FC
   ...                                   ...
  EF40 ... EF7E, EF80 ... EF9E, EF9F ... EFFC
  F040 ... F07E, F080 ... F09E, F09F ... F0FC : 以下 CP932 のみ
   ...                                   ...
  FC40 ... FC7E, FC80 ... FC9E, FC9F ... FCFC
範囲
JIS(1) 21:22 - 5D:5E 5F:60 - 7D:7E
CP932(1) 81 - 9F E0 - EF F0 - FC
JIS(2) 21 - 5F 60 - 7E 21 - 7E
CP932(2) 40 - 7E 80 - 9E 9F - FC
Shift-JIS を EUC に変換するサンプル プログラム
c
#include <stdio.h>

unsigned int is_sj(unsigned char c)
{
    return (((c ^ 0xa0) - 0x21) < 0x3c);
}

unsigned int sj2j(unsigned char h, unsigned char l)
{
    unsigned int jh = ((h ^ 0xa0) - 0x21) << 9;
    unsigned int jl = (l - 0x1f /* -40+21 */
                       + (l >= 0x80 ?   -1 : 0)
                       + (l >= 0x9F ? 0xa2 : 0)); /* A2 = 1F+01-9F+21+100 */
    return (jh + jl + 0x2100);
}

int main()
{
    int c1, c2, sj;

    while ((c1 = fgetc(stdin)) != EOF)
    {
        if (!is_sj(c1))
        {
            /* 半角カナは非対応 */
            fputc(c1, stdout);
            continue;
        }
        c2 = fgetc(stdin);
        if (c2 == EOF)
        {
            fputc(c1, stdout);
            break;
        }
        sj = sj2j(c1, c2); /* CP932 のみ領域は非対応 */
        c1 = sj >> 8;
        c2 = sj & 0xff;
        fputc(0x80 | c1, stdout);
        fputc(0x80 | c2, stdout);
    }
    return 0;
}

これを gcc -O3 -S -g0 でコンパイルした結果が興味深い。
main のインライン展開された sj2j は条件代入が使用されているが、
sj2j 関数は条件分岐になっている(保存レジスタの使用を避けるため?)。

asm
	.text
	.p2align 4,,15
	.globl	is_sj
	.type	is_sj, @function
is_sj:
.LFB23:
	.cfi_startproc
	xorl	$-96, %edi
	xorl	%eax, %eax
	cmpb	$92, %dil
	setbe	%al
	ret
	.cfi_endproc
.LFE23:
	.size	is_sj, .-is_sj
	.p2align 4,,15
	.globl	sj2j
	.type	sj2j, @function
sj2j:
.LFB24:
	.cfi_startproc
	xorl	$-96, %edi
	movzbl	%sil, %eax
	movzbl	%dil, %edi
	subl	$33, %edi
	sall	$9, %edi
	testb	%sil, %sil
	js	.L4
	leal	-31(%rax), %edx
	xorl	%eax, %eax
	addl	%edx, %eax
	leal	8448(%rdi,%rax), %eax
	ret
	.p2align 4,,10
	.p2align 3
.L4:
	cmpb	$-97, %sil
	leal	-32(%rax), %edx
	sbbl	%eax, %eax
	notl	%eax
	andl	$162, %eax
	addl	%edx, %eax
	leal	8448(%rdi,%rax), %eax
	ret
	.cfi_endproc
.LFE24:
	.size	sj2j, .-sj2j
	.section	.text.startup,"ax",@progbits
	.p2align 4,,15
	.globl	main
	.type	main, @function
main:
.LFB25:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	pushq	%rbx
	.cfi_def_cfa_offset 24
	.cfi_offset 3, -24
	subq	$8, %rsp
	.cfi_def_cfa_offset 32
	.p2align 4,,10
	.p2align 3
.L8:
	movq	stdin(%rip), %rdi
	call	fgetc@PLT
	cmpl	$-1, %eax
	movl	%eax, %ebp
	je	.L12
	movl	%ebp, %ebx
	xorl	$-96, %ebx
	cmpb	$92, %bl
	ja	.L16
	movq	stdin(%rip), %rdi
	call	fgetc@PLT
	cmpl	$-1, %eax
	je	.L17
	movzbl	%al, %edx
	movsbl	%al, %ecx
	movzbl	%bl, %ebx
	shrl	$31, %ecx
	subl	$31, %edx
	sall	$9, %ebx
	subl	%ecx, %edx
	cmpb	$-98, %al
	movq	stdout(%rip), %rsi
	leal	162(%rdx), %ecx
	cmova	%ecx, %edx
	leal	-8448(%rbx,%rdx), %ebx
	movl	%ebx, %edi
	sarl	$8, %edi
	orb	$-128, %dil
	call	fputc@PLT
	movq	stdout(%rip), %rsi
	movzbl	%bl, %edi
	orb	$-128, %dil
	call	fputc@PLT
	jmp	.L8
	.p2align 4,,10
	.p2align 3
.L16:
	movq	stdout(%rip), %rsi
	movl	%ebp, %edi
	call	fputc@PLT
	jmp	.L8
.L17:
	movq	stdout(%rip), %rsi
	movl	%ebp, %edi
	call	fputc@PLT
.L12:
	addq	$8, %rsp
	.cfi_def_cfa_offset 24
	xorl	%eax, %eax
	popq	%rbx
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE25:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
	.section	.note.GNU-stack,"",@progbits
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?