Size: a a a

Ассемблер

2021 August 23

D

Den in Ассемблер
Мощность калькулятора невероятно увеличилась, но возмошны баги! :))
источник

E

Entusiast in Ассемблер
@disba1ancer @laurson
Как сделать, чтоб Си нормально брал первое число и последнее число?
getfirst(int):
       mov eax, 0x20000001
.L4:
       mov     edx, eax
       lea     eax, [eax+15]
       test    edx, edx
       cmovns  eax, edx
       sar     eax, 4
       cmp     edx, 271
       jg      .L4
       ret
Выходит намного медленнее, чем:
  mov eax, 0x20000001
   
   @@:
   cmp eax, 0x10
   jb  @f
   shr eax, 4
   jmp @b
   @@:

Получение последнего числа нормально сделал, через маску:
and eax, 0xF
:
        mov     eax, 0x2000001
       cdq
       shr     edx, 28
       add     eax, edx
       and     eax, 15
       sub     eax, edx
(Если что, я про HEX число - первое и последнее)

int getlast(int num) {
   return (num % 0x10);
}

int getfirst(int num) {
   while((num /= 0x10) > 0x10) {  }
   return num;
}
источник

E

Entusiast in Ассемблер
Всё, понял. Логично напрямую написать сдвиг в Си
источник

s

s54816 in Ассемблер
Bit scan точно медленнее, чем твои циклы?
источник

E

Entusiast in Ассемблер
Да, проверял всеми способами
источник

E

Entusiast in Ассемблер
Так темболее там тоже цикл
источник

s

s54816 in Ассемблер
Какой там цикл? Нашёл бит, округлил, всё.
источник

E

Entusiast in Ассемблер
Ну при маленьких значениях типа 0x20 - конечно цикл медленнее
источник

E

Entusiast in Ассемблер
Нет, в отладчике проверял - 0x20000001 просто по циклу гоняет
источник

s

s54816 in Ассемблер
Я тебе не об этом говорю. Зачем тебе в принципе цикл, когда ты можешь bsr или __builtin_clz?
источник

E

Entusiast in Ассемблер
Не понял, что за техника такая
источник

s

s54816 in Ассемблер
Ты хочешь старший ненулевой шестнадцатеричный разряд, так?
источник

E

Entusiast in Ассемблер
Да
источник

s

s54816 in Ассемблер
Окей. Ты можешь найти старший двоичный разряд процессором (bsr, lzcnt), а не явным циклом. Этот разряд будет частью (какого-то) шестнадцатеричного. Значит ты можешь округлить его вниз (bit_pos &= ~3) и тем самым вычислить сразу необходимый сдвиг. Ну и потом return (value >> bit_pos) & 15, как обычно. Я не уверен, будет ли это быстрее на маленьких значениях, и даже думать не хочу, но циклов с таким подходом не будет вообще.
источник

AP

Andrey P in Ассемблер
коллеги, раз про стек говорите. нубский вопрос. какой размер стекового сегмента по умолчанию для 16, 32 и 64 бит? меняется ли он?
источник

AP

Andrey P in Ассемблер
для 16 вроде 64кб
источник

s

s54816 in Ассемблер
В 16-битном реальном режиме все сегменты 64к. В защищённом 16/32 можно задать с точностью до байта в дескрипторе сегмента, в 64 лимита нет. Но это сегмент ss. А вот размер самого стека зависит от ОС — сколько она выделит, столько и будет. Например, в MS-DOS для .exe можно указать, .com стартует так, что там всё в одном сегменте, поэтому без дополнительных манипуляций 64к минус 256 байт PSP, минус 2, минус код и переменные. В винде ты указываешь требуемый и максимальный размеры в .exe, и стек потихоньку растёт до максимума. Потоку можешь при создании отдельно размер задать.
источник

AP

Andrey P in Ассемблер
окей. а задается на этапе компиляции, как я понял?
источник

s

s54816 in Ассемблер
Да.
источник

AP

Andrey P in Ассемблер
спасибо. понял
источник