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?

C言語の型変換をARM32アセンブリで確認する(int, short, float)

Posted at

目的

前回x86でC言語のキャストが、実際にどのように型変換を行っているかを調べた。
今回は32ビットARMで同じ検証をする。

C言語の型変換をx86アセンブリで確認する(int, short, float)

gcc -O0 -S test.c -o test.s

int -> short

intは4バイト
shortは2バイト
strh命令でr3レジスタの下位16ビットをメモリへ格納している。
ここでintからshortへ変換している。

int a=100;
short b=(short)a;
movs    r3, #100
str     r3, [r7, #4]
ldr     r3, [r7, #4]
strh    r3, [r7, #2]    @ movhi
元のコード
test.c
int main(){
    int a=100;
    short b=(short)a;
    return 0;
}
test.s
        .arch armv7-a
        .fpu vfpv3-d16
        .eabi_attribute 28, 1
        .eabi_attribute 20, 1
        .eabi_attribute 21, 1
        .eabi_attribute 23, 3
        .eabi_attribute 24, 1
        .eabi_attribute 25, 1
        .eabi_attribute 26, 2
        .eabi_attribute 30, 6
        .eabi_attribute 34, 1
        .eabi_attribute 18, 4
        .file   "test.c"
        .text
        .align  1
        .global main
        .syntax unified
        .thumb
        .thumb_func
        .type   main, %function
main:
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 1, uses_anonymous_args = 0
        @ link register save eliminated.
        push    {r7}
        sub     sp, sp, #12
        add     r7, sp, #0
        movs    r3, #100
        str     r3, [r7, #4]
        ldr     r3, [r7, #4]
        strh    r3, [r7, #2]    @ movhi
        movs    r3, #0
        mov     r0, r3
        adds    r7, r7, #12
        mov     sp, r7
        @ sp needed
        ldr     r7, [sp], #4
        bx      lr
        .size   main, .-main
        .ident  "GCC: (Debian 12.2.0-14+deb12u1) 12.2.0"
        .section        .note.GNU-stack,"",%progbits

short -> int

ldrshは16ビットの符号を保ったままビットに広げる命令

short b=100;
int a=(int)b;
movs    r3, #100
strh    r3, [r7, #6]    @ movhi
ldrsh   r3, [r7, #6]
str     r3, [r7]
元のコード
test.c
int main(){
    short b=100;
    int a=(int)b;
    return 0;
}
test.s
        .arch armv7-a
        .fpu vfpv3-d16
        .eabi_attribute 28, 1
        .eabi_attribute 20, 1
        .eabi_attribute 21, 1
        .eabi_attribute 23, 3
        .eabi_attribute 24, 1
        .eabi_attribute 25, 1
        .eabi_attribute 26, 2
        .eabi_attribute 30, 6
        .eabi_attribute 34, 1
        .eabi_attribute 18, 4
        .file   "test.c"
        .text
        .align  1
        .global main
        .syntax unified
        .thumb
        .thumb_func
        .type   main, %function
main:
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 1, uses_anonymous_args = 0
        @ link register save eliminated.
        push    {r7}
        sub     sp, sp, #12
        add     r7, sp, #0
        movs    r3, #100
        strh    r3, [r7, #6]    @ movhi
        ldrsh   r3, [r7, #6]
        str     r3, [r7]
        movs    r3, #0
        mov     r0, r3
        adds    r7, r7, #12
        mov     sp, r7
        @ sp needed
        ldr     r7, [sp], #4
        bx      lr
        .size   main, .-main
        .ident  "GCC: (Debian 12.2.0-14+deb12u1) 12.2.0"
        .section        .note.GNU-stack,"",%progbits

int -> float

int a = 42;
float f;
f = (float)a;
movs    r3, #42
str     r3, [r7, #4]
ldr     r3, [r7, #4]
vmov    s15, r3 @ int42をFPレジスタs15に複製
vcvt.f32.s32    s15, s15 @ 32bit整数→32bit浮動小数点に変換
vstr.32 s15, [r7]
元のコード
test.c
int main() {
    int a = 42;
    float f;
    f = (float)a;
    return 0;
}
test.c
        .arch armv7-a
        .fpu vfpv3-d16
        .eabi_attribute 28, 1
        .eabi_attribute 20, 1
        .eabi_attribute 21, 1
        .eabi_attribute 23, 3
        .eabi_attribute 24, 1
        .eabi_attribute 25, 1
        .eabi_attribute 26, 2
        .eabi_attribute 30, 6
        .eabi_attribute 34, 1
        .eabi_attribute 18, 4
        .file   "test.c"
        .text
        .align  1
        .global main
        .syntax unified
        .thumb
        .thumb_func
        .type   main, %function
main:
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 1, uses_anonymous_args = 0
        @ link register save eliminated.
        push    {r7}
        sub     sp, sp, #12
        add     r7, sp, #0
        movs    r3, #42
        str     r3, [r7, #4]
        ldr     r3, [r7, #4]
        vmov    s15, r3 @ int
        vcvt.f32.s32    s15, s15
        vstr.32 s15, [r7]
        movs    r3, #0
        mov     r0, r3
        adds    r7, r7, #12
        mov     sp, r7
        @ sp needed
        ldr     r7, [sp], #4
        bx      lr
        .size   main, .-main
        .ident  "GCC: (Debian 12.2.0-14+deb12u1) 12.2.0"
        .section        .note.GNU-stack,"",%progbits

float -> int

float f = 12.3;
int a;
a = (int)f;
movw    r3, #52429
movt    r3, 16708
str     r3, [r7, #4]    @ float
vldr.32 s15, [r7, #4]
vcvt.s32.f32    s15, s15 @ float → int に変換
vmov    r3, s15 @ int
str     r3, [r7]
元のコード
test.c
int main() {
    float f = 12.3;
    int a;
    a = (int)f;
    return 0;
}
test.s
        .arch armv7-a
        .fpu vfpv3-d16
        .eabi_attribute 28, 1
        .eabi_attribute 20, 1
        .eabi_attribute 21, 1
        .eabi_attribute 23, 3
        .eabi_attribute 24, 1
        .eabi_attribute 25, 1
        .eabi_attribute 26, 2
        .eabi_attribute 30, 6
        .eabi_attribute 34, 1
        .eabi_attribute 18, 4
        .file   "test.c"
        .text
        .align  1
        .global main
        .syntax unified
        .thumb
        .thumb_func
        .type   main, %function
main:
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 1, uses_anonymous_args = 0
        @ link register save eliminated.
        push    {r7}
        sub     sp, sp, #12
        add     r7, sp, #0
        movw    r3, #52429
        movt    r3, 16708
        str     r3, [r7, #4]    @ float
        vldr.32 s15, [r7, #4]
        vcvt.s32.f32    s15, s15
        vmov    r3, s15 @ int
        str     r3, [r7]
        movs    r3, #0
        mov     r0, r3
        adds    r7, r7, #12
        mov     sp, r7
        @ sp needed
        ldr     r7, [sp], #4
        bx      lr
        .size   main, .-main
        .ident  "GCC: (Debian 12.2.0-14+deb12u1) 12.2.0"
        .section        .note.GNU-stack,"",%progbits

まとめ

int -> short strh命令を使い、上位16ビットを切り捨てている。
short -> int ldrsh命令を使って拡張している。
int -> float vcvt.f32.s32命令を使って変換している。
float -> int vcvt.s32.f32命令を使って変換している。

動作環境(Linux / ARM 版)

OS: Armbian 23.08.0-trunk (Debian 12 Bookworm)
Kernel: Linux 6.1.38-meson (armv7l)
CPU: ARM Cortex-A5, 4 cores, Little Endian
GCC: 12.2.0
Architecture: armv7l
備考: Windows10からSSH接続して使用

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?