Нумерация битов, байтов

Тема в разделе "WASM.HEAP", создана пользователем Entropy, 12 май 2023.

  1. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    175
    Часто становится весьма непривычно, что нумерация начинается с 0 а не 1 и это немного сбивает, может быть программирование это не моё, раз меня такие простые вещи сбивают с толку, как к этому привыкнуть?
     
  2. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.955
    А выражение "времени третий час дня" не сбивает с толку, когда на часах 14:хх Или "на пятом десятке лет", когда человеку 4х лет? А "Восемнадцатый век", когда про 17хх год говорят? Это еще фигня, бывает бит 0 - старший, а 7 младший в байте.
    изображение_2023-05-12_140843791.png
     
  3. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    441
    Просто для нумерации битов используй тоже биты. Тогда восемь бит байта будут нумероваться по порядку комбинациями из трёх бит:
    000
    001
    010
    011
    100
    101
    110
    111
    Теперь если раздавать им значащие имена, то слово "нулевой" появится само собой.
     
  4. dcc0

    dcc0 Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    60
    Если поработать с массивами в C или PHP, то в этих языках явно видно, что с 0 нумерация чаще.
    Ещё не всегда понятно, где последняя итерация в циклах, тоже интересная тема.
     
  5. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    861
    С нуля удобно нумеровать когда устанавливаешь биты. Такое часто используется в AVR микроконтроллерах. К примеру установить биты GICR |= (1 << INT0) | (1 << INT1); - разрешить прерывания INT0 и INT1. Если нумеровать с 1 то такое не получится.
     
  6. mantissa

    mantissa Мембер Команда форума

    Публикаций:
    0
    Регистрация:
    9 сен 2022
    Сообщения:
    138
    Пример на массивах в C:
    Массив - последовательность однотипных данных в памяти, по сути это - указатель на память, где этот массив начинается, соответственно 0(первый) элемент находится на этом же месте, т.е его смещение равно 0 (адрес массива + 0). Для второго элемента смещение 1, для третьего 2 и тд. Но стоит учесть, что в записи "указатель + смещение" знак "+" задается арифметическим шагом, который равен размеру элемента в массиве в байтах. То есть, например, для int (4 байта) - запись "адрес + 1" будет значить "адрес + 4".
    upload_2023-5-12_21-18-24.png
     
    DrochNaNoch нравится это.
  7. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.250
    Это - наследие из чудесного единственно рассово верного языка Цэ, где конструкция array[1] - просто синтаксический сахар над указателями, типа *(array + 1), поэтому первый элемент массива оказывается нулевым. Забавно, что эта особенность позволяет в Цэ делать угарную для нубов вещь, типа 1[array] и получать тот же результат, поскольку от перестановки мест слагаемый сумма не меняется. Добро пожаловать в удивительный мир старых языков программирования и их культурного наследия в новых языках программирования...
    --- Сообщение объединено, 12 май 2023 ---
    И еще есть же Lua и еще несколько языков, где нумерация массивов происходит с единицы, но привыкать к этому, наверное, не стоит, если не хочешь всю жизнь писать на одном языке.
     
  8. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    441
    Конкретно это - это наследие языка B, предшественника C. В нём не было по сути типов данных кроме слов. И понять чем слово является - переменной или указателем можно было только из контекста применения - по окружающим символам. Поэтому 1[var] и var[1] в B транслировались в одно и то же - сложение двух слов с получением l-value по полученному адресу. Скорее всего он с таким же успехом переварил бы и 2[1]. И скорее всего поэтому в Си есть два разных оператора - operator. и operator-> - потому что опять таки в B видимо нужна была разница в операторах чтобы понять чем слово слева является - указателем на первое слово структуры или l-value экземпляром первого слова в структуре. Как то так. Причём я когда то давно находил, что структуры в самых даже первых не вышедших далеко из лаборатории версиях Си видимо по аналогии с B реализовались тем, что их поля были глобальными идентификаторами с численными значениями-смещениями, поэтому там прям как в ассемблере надо было делать типа point.Point2ВX, типа такого. Но это прям слабо известно, т.к. не дожило даже до первого бестселлера Кернигана и Ритчи.
     
  9. mantissa

    mantissa Мембер Команда форума

    Публикаций:
    0
    Регистрация:
    9 сен 2022
    Сообщения:
    138
    а в чем отличие? по сути поля это и есть смещение от базы, только именованное. а оператор -> лишь сахар для *(pointer).field
     
  10. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    562
    С/С++ это довольно низкоуровневый язык(да, масло масленое, вода мокрая)
    Просто надо разбивать команды на микрокоманды, на самые элементарные микрокоманды.
    mov eax, [ebx+666h]
    shM:=ebx+666h ; локальный аппаратный регистр
    eax:=[shM] ;на самом деле тут куча микрокоманд, зависит от сложности процессора.
    666h это смещения какого-та параметра в структуре или классе, что одно и тоже, и 0 это тоже смещения, может на виртуальную таблицу методов класса. Так что с нуля это естественно, по другому просто не может быть, на оборот с единицы это не правильно.
    Так же нумерация бит работает.
     
  11. MaKsIm

    MaKsIm Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    68
    Нумерация с 1 прижилась в типах типа ShortString, где первый элемент (с 0 индексом) описывал длину строки, а строка начиналась с 1 индекса.

    Еще можно вспомнить про функцию ah=10/int 33, для которой в dx задается буфер начинающийся с длины самого буфера и в первом байте возвращается длина строки.
     
  12. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    441
    В глобальности. Имена полей разных структур не могли совпадать.
     
    mantissa нравится это.
  13. mantissa

    mantissa Мембер Команда форума

    Публикаций:
    0
    Регистрация:
    9 сен 2022
    Сообщения:
    138
    Ну и еще пример со структурами, там все точно также как и в массивах, указатель на структуру - указатель на первый элемент структуры.
    Код (Text):
    1. typedef struct Person {
    2.     int age;
    3.     int h;
    4.     int w;
    5. } Person;
    6.  
    7. int main()
    8. {
    9.     void* offset = (&((Person*)0)->h);
    10.     printf("%x", offset);
    11.     return 0;
    12. }
     
  14. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    175
    Начинаю к этому немного привыкать

    Код (ASM):
    1.  
    2. format PE64 console
    3.  
    4.  
    5.  
    6. include 'win64a.inc'
    7.  
    8.  
    9.  
    10. section '.text' readable executable
    11.  
    12.  
    13.  
    14.  
    15. mov rax,mass
    16. xor rcx,rcx
    17.  
    18.  
    19.  
    20. poll:
    21.  
    22. mov byte [rax],0xD3 ;заполняем нулевой элемент
    23. inc rcx   ;а потом регистр rcx увеличиваем на 1
    24. inc rax
    25. cmp rcx,255   ;256 элементов
    26. je mrq
    27. jmp poll
    28.  
    29.  
    30.  
    31.  
    32.  
    33.  
    34.  
    35. mrq:
    36.  
    37. sub rsp,8
    38. invoke MessageBoxA,0,addr message,addr caption,0
    39.  
    40.  
    41.  
    42. invoke ExitProcess,0
    43.  
    44.  
    45.  
    46. section '.data' readable writeable
    47.  
    48.  
    49. mass db 256 dup(0)
    50.  
    51.  
    52. caption db 'JUMP',0
    53.  
    54. message db 'COMPARE',0
    55.  
    56.  
    57.  
    58.  
    59. section '.idata' import data readable writeable
    60.  
    61. library kernel32,'kernel32.dll',\
    62.         user32,'user32.dll'
    63.  
    64.  
    65. include 'api\kernel32.inc'
    66. include 'api\user32.inc'  
    67.  
     
  15. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    Entropy,
    Код (ASM):
    1.    xor eax,eax
    2. poll: mov mass[rax],0xD3 ;заполняем нулевой элемент
    3.    inc eax
    4.    or ah,ah ;256 элементов
    5.    je poll
     
  16. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Mikl___,
    Код (ASM):
    1.  
    2. lea rdi, mass
    3. mov rax, 0d3d3d3d3d3d3d3d3h
    4. mov rcx, 256 / 8
    5. rep stosq
    6.  
     
    Entropy и Mikl___ нравится это.
  17. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    175
  18. R81...

    R81... Active Member

    Публикаций:
    0
    Регистрация:
    1 фев 2020
    Сообщения:
    141
    Конечно же rmn, но
    Код (ASM):
    1.   Mov eDi, offset [mass] ; в 32-х короче "lea edi, mass" как в 64-х ?
    2.   Mov Al, 0d3h
    3.   Mov eCx, 256
    4.   ClD ; в 32-х не всегда по умолчанию вперед (как в 64-х не знаю).
    5.   rep StosB
    А может процессор умный по скорости? А по памяти меньше кода.
     
  19. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    R81...,
    Ну, можно написать
    Код (ASM):
    1.  
    2. lea rdi, mass
    3. mov al, 0d3h
    4. mov rcx, 256
    5. rep stosb
    6.  
    если прям так памяти не хватает :) На глаз тут байт 18

    lea и mov должны быть одного размера: там опкод, modrm и смещение.
    --- Сообщение объединено, 1 июн 2023 ---
    всегда (если ты, конечно, сам перед этим этот флаг не трогал).
     
  20. MaKsIm

    MaKsIm Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    68
    Для mov может не уместиться в 7-байтовый опкод. Зависит от базового адреса. И тогда mov будет 9 байтовый. Тогда как lea для 64-бит будет 7 байтовый всегда т.к. можно вычислять адреса относительно rip
    --- Сообщение объединено, 2 июн 2023 ---
    В 64-битах также есть флаг DF