Глюк при левом шифте.

Тема в разделе "WASM.ASSEMBLER", создана пользователем Songoku, 19 фев 2011.

  1. Songoku

    Songoku Эдгар

    Публикаций:
    0
    Регистрация:
    1 мар 2003
    Сообщения:
    68
    Адрес:
    Belarus
    В Visual C++ хотел следующее следать:
    unsigned int d = (0x22224444<<0xAAA9DDDD);

    по идее d должно быть равно 0, но незультат равен 0x80000000,
    глянул в assembler код выглядит таким образом

    mov edi, 0x22224444
    mov ecx, 0xAAA9DDDD
    shl edi, cl

    ок, тут видно что из ecx берётся только cl то есть 0xDD, но всё равно это в 6 раз больше чем 32 бита
     
  2. Sunzer

    Sunzer Member

    Публикаций:
    0
    Регистрация:
    25 май 2008
    Сообщения:
    256
    А в чем собственно ошибка по вашему мнению? Что нельзя сдвинуть на 0xAAA9DDDD?
     
  3. Atlantic

    Atlantic Member

    Публикаций:
    0
    Регистрация:
    22 июн 2005
    Сообщения:
    322
    Адрес:
    Швеция
    shl берет только младшие 5 бит из cl - это будут 11101 в твоем случае, то есть 29. Получается:
    unsigned int d = (0x22224444<<29);
     
  4. Songoku

    Songoku Эдгар

    Публикаций:
    0
    Регистрация:
    1 мар 2003
    Сообщения:
    68
    Адрес:
    Belarus
    Да можно, но результат должен быть 0, а он 0x80000000.
    0xAAA9DDDD больше 32, соответственно число должно уйти за пределы edi.
     
  5. Songoku

    Songoku Эдгар

    Публикаций:
    0
    Регистрация:
    1 мар 2003
    Сообщения:
    68
    Адрес:
    Belarus
    Жесть, а решение проблемы есть?
     
  6. Atlantic

    Atlantic Member

    Публикаций:
    0
    Регистрация:
    22 июн 2005
    Сообщения:
    322
    Адрес:
    Швеция
    Если тебе так надо обнулить регистр через shl, нужно сдвигать ровно на 32.
     
  7. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    это UB.
     
  8. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    Songoku
    Код (Text):
    1. unsigned int d=0;
     
  9. Songoku

    Songoku Эдгар

    Публикаций:
    0
    Регистрация:
    1 мар 2003
    Сообщения:
    68
    Адрес:
    Belarus
    Всё проблема решина, всем большое спасибо, особенно Atlantic.
    Оказалось что есть процессоры которые 5 бит берут и которые 8.
    Для этого я сделал следующее, предположим d = x<<y;
    d = ((y & 0xFF) > 31 ? 0 : x << y );
     
  10. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    В природе не только 32-битные процессоры существуют вообще-то...
     
  11. Songoku

    Songoku Эдгар

    Публикаций:
    0
    Регистрация:
    1 мар 2003
    Сообщения:
    68
    Адрес:
    Belarus
    cppasm
    Вообще-то я портировал код c x86 на ARM11.
     
  12. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    А при y = 0x100 , что будет? Снова тупая попытка сдвига?
     
  13. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    T800
    вероятно, имеется в виду, что y это байт.
     
  14. Songoku

    Songoku Эдгар

    Публикаций:
    0
    Регистрация:
    1 мар 2003
    Сообщения:
    68
    Адрес:
    Belarus
    y это любое число, но когда дело доходит до сдвига в x86 берутся первые 5 бит, а в ARM 8 бит.
    Например мы хотим сдвинуть на лево число 1 на 97(0b1100001), x86 селектирует только первые 5 бит 0b1100001 получается только 1, соответсвенно результат равен 2.
    ARM в свою очередь селектирует первые 8 бит 0b01100001 получается 97, соответсвенно результат уходит за границы 32 бит и равен 0.
     
  15. LShadow77

    LShadow77 New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2010
    Сообщения:
    36
    Та народ, шо вы паритесь:

    xor edi,edi
    mov ecx,y
    test ecx,0ffffffe0h
    jnz @F
    mov edi,x
    shl edi,cl
    @@:
    mov x,edi

    Или, если говоря сишным языком:

    x = (unsigned int)y<32 ? x<<y : 0