2013-08-16 2 views
1

Когда я перекрестно скомпилировал приложение для цели с ядром Armv7, переменные с «длинным длинным int» неправильно напечатаны.значения длинного длинного int неверно напечатаны

typedef long long int vmm_int64; 
typedef unsigned long long int vmm_uint64; 

int main(int argc, char *argv[]) 
{ 
    vmm_int64 a, b, result; 

    a = 5; 
    b = 24; 
    result = 0; 

    printf("Initial Values are:\n"); 
    printf("\t a : %lld \n", a); 
    printf("\t b : %lld \n", b); 
    printf("\t result : %lld \n", result); 

    fflush(stdout); 

    result = a + b; 

    printf("Final Values are:\n"); 
    printf("\t a : %lld \n", a); 
    printf("\t b : %lld \n", b); 
    printf("\t result : %lld \n", result); 

    fflush(stdout); 

    return 0; 
} 

Выход следующим образом:

Initial Values are: 
    a : 23639177792 
    b : 105243556416 
    result : 2164341312 
Final Values are: 
    a : 23639177792 
    b : 105243556416 
    result : 126718392896 

Может кто-то пожалуйста, объясните, что здесь происходит? Что я должен сделать, чтобы все исправить?

После еще некоторого анализа, я только заметил, что

a = 0x5 (0x00000005 81013a44 which is hex for 23639177792) 
b = 0x18 (0x00000018 81013a40 which is hex for 105243556416) 

i. result = 0 (0x00000000 81013a40 which is hex for 2164341312) 
ii. result = 0x1D (0x0000001D 81013a40 which is hex for 126718392896) 

Верхние 32 бита содержат правильные значения. Я просто не понимаю, почему

  1. В результате верхнее/нижнее слово заменено.
  2. Даже если слова были заменены, почему в младшем слове есть барахло.

Компилятор Информация:

arm-none-eabi-gcc -v 
Using built-in specs. 
COLLECT_GCC=c:\Program Files\CodeSourcery\Sourcery G++ Lite\bin\arm-none-eabi-gcc.exe 
COLLECT_LTO_WRAPPER=c:/program files/codesourcery/sourcery g++ lite/bin/../libexec/gcc/arm-none-eabi/4.5.2/lto-wrapper.exe 
Target: arm-none-eabi 
Configured with: /scratch/janisjo/arm-eabi-lite/src/gcc-4.5-2011.03/configure --build=i686-pc-linux-gnu --host=i686-mingw32 --target=arm-none-eabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --enable-extra-sgxxlite-multilibs --with-gnu-as --with-gnu-ld --with-specs='%{save-temps: -fverbose-asm} -D__CS_SOURCERYGXX_MAJ__=2011 -D__CS_SOURCERYGXX_MIN__=3 -D__CS_SOURCERYGXX_REV__=42 %{O2:%{!fno-remove-local-statics: -fremove-local-statics}} %{O*:%{O|O0|O1|O2|Os:;:%{!fno-remove-local-statics: -fremove-local-statics}}}' --enable-languages=c,c++ --disable-shared --enable-lto --with-newlib --with-pkgversion='Sourcery G++ Lite 2011.03-42' --with-bugurl=https://support.codesourcery.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-headers=yes --with-sysroot=/opt/codesourcery/arm-none-eabi --with-build-sysroot=/scratch/janisjo/arm-eabi-lite/install/host-i686-mingw32/arm-none-eabi --with-libiconv-prefix=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --with-gmp=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --with-mpfr=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --with-mpc=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --with-ppl=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-cloog=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --with-libelf=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --disable-libgomp --enable-poison-system-directories --with-build-time-tools=/scratch/janisjo/arm-eabi-lite/obj/tools-i686-pc-linux-gnu-2011.03-42-arm-none-eabi-i686-mingw32/arm-none-eabi/bin --with-build-time-tools=/scratch/janisjo/arm-eabi-lite/obj/tools-i686-pc-linux-gnu-2011.03-42-arm-none-eabi-i686-mingw32/arm-none-eabi/bin 
Thread model: single 
gcc version 4.5.2 (Sourcery G++ Lite 2011.03-42) 
+3

Невозможно воспроизвести. Вы '# include''ing' '? –

+0

Я получаю: Начальные значения являются: \t: с 5 \t б: 24 \t результат: 0 Итоговые значения являются: \t а: 5 \t б: 24 \t результат: 29 –

+0

код был крест -компилирован с использованием G ++ для ARM из Code Sourcery. – Girish

ответ

1

Похоже, вы смешиваете АБИС. Вероятно, ваш кросс-компилятор использует APCS (aka Old ABI), в то время как Android runtime ожидает EABI.

Важным отличием между ними является то, как 64-битные значения передаются в регистры. Старый ABI использует следующую доступную пару регистров, например.

; printf("\t a : %lld \n", a); 
load format string into R0 
load 'a' into R1 and R2 
call printf 

в то время как EABI использует следующий даже выровненный регистра пары:

; printf("\t a : %lld \n", a); 
load format string into R0 
load 'a' into R2 and R3 
call printf 

Давайте посмотрим, как a будет принят для обоих АБИС:

1. Фактические: 5 = 0 (high32) и 5 ​​(low32)

OABI: R1 = 0, R2 = 5
EABI: R2 = 0, R 3 = 5

  1. Printed: 23639177792 = 0x581013A40 = 0x5 (high32) и 0x81013A40 (low32)

    OABI: R1 = 5, R2 = 0x81013A40
    EABI: R2 = 5, R 3 = 0x81013A40

Таким образом, скорее всего, ваш код загружен 0 в R1 и 5 в R2, но printf интерпретируется R2 как высокая часть и мусора от R3 как низкая часть. Вы можете легко проверить его, проверив сгенерированную сборку.

Исправление должно быть простым - используйте параметр компилятора для генерации кода EABI или просто используйте инструментальную цепочку, специально предназначенную для Android, например. Android NDK.

EDIT: Я имел высокие и низкие части меняются местами. Вот правильный вариант:

  1. Фактическое: 5 = 0 (high32) и 5 ​​(low32)

    OABI: R1 = 5, R2 = 0
    EABI: R2 = 5, R 3 = 0

  2. Printed: 23639177792 = 0x581013A40 = 0x5 (high32) и 0x81013A40 (low32)

    OABI: R1 = 0x81013A40, R2 = 5
    EABI: R2 = 0x81013A40, R 3 = 5

Таким образом, фактические данные свидетельствуют о противоположном: ваш код использует EABI, тогда как printf ожидает OABI.

+0

Это кажется более разумным. Я просто посмотрел на разборку. Вот как это происходит. 'printf (" \ t a:% lld \ n ", a); movs r2, # 0x5 movs r3, # 0x0 ldr r0, 0x800104d4 bl 0x80015b00 (что относится к функции print libray) ' – Girish

+0

из вашего комментария Я делаю вывод, что EABI - это текущий режим компилятора – Girish

+0

Итак, моя теория неверна, есть что-то еще. –