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

Discussion in 'WASM.HEAP' started by Entropy, May 12, 2023.

  1. Entropy

    Entropy Member

    Blog Posts:
    0
    Joined:
    Aug 23, 2020
    Messages:
    185
    Часто становится весьма непривычно, что нумерация начинается с 0 а не 1 и это немного сбивает, может быть программирование это не моё, раз меня такие простые вещи сбивают с толку, как к этому привыкнуть?
     
  2. f13nd

    f13nd Well-Known Member

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

    aa_dav Active Member

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

    dcc0 Member

    Blog Posts:
    2
    Joined:
    Dec 22, 2022
    Messages:
    81
    Если поработать с массивами в C или PHP, то в этих языках явно видно, что с 0 нумерация чаще.
    Ещё не всегда понятно, где последняя итерация в циклах, тоже интересная тема.
     
  5. Thetrik

    Thetrik UA6527P

    Blog Posts:
    0
    Joined:
    Jul 25, 2011
    Messages:
    887
    С нуля удобно нумеровать когда устанавливаешь биты. Такое часто используется в AVR микроконтроллерах. К примеру установить биты GICR |= (1 << INT0) | (1 << INT1); - разрешить прерывания INT0 и INT1. Если нумеровать с 1 то такое не получится.
     
  6. mantissa

    mantissa Мембер Staff Member

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

    Rel Well-Known Member

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

    aa_dav Active Member

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

    mantissa Мембер Staff Member

    Blog Posts:
    0
    Joined:
    Sep 9, 2022
    Messages:
    170
    а в чем отличие? по сути поля это и есть смещение от базы, только именованное. а оператор -> лишь сахар для *(pointer).field
     
  10. Intro

    Intro Active Member

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

    MaKsIm Active Member

    Blog Posts:
    0
    Joined:
    Feb 11, 2008
    Messages:
    151
    Нумерация с 1 прижилась в типах типа ShortString, где первый элемент (с 0 индексом) описывал длину строки, а строка начиналась с 1 индекса.

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

    aa_dav Active Member

    Blog Posts:
    0
    Joined:
    Dec 24, 2008
    Messages:
    525
    В глобальности. Имена полей разных структур не могли совпадать.
     
    mantissa likes this.
  13. mantissa

    mantissa Мембер Staff Member

    Blog Posts:
    0
    Joined:
    Sep 9, 2022
    Messages:
    170
    Ну и еще пример со структурами, там все точно также как и в массивах, указатель на структуру - указатель на первый элемент структуры.
    Code (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

    Blog Posts:
    0
    Joined:
    Aug 23, 2020
    Messages:
    185
    Начинаю к этому немного привыкать

    Code (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___ Супермодератор Staff Member

    Blog Posts:
    14
    Joined:
    Jun 25, 2008
    Messages:
    3,914
    Entropy,
    Code (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

    Blog Posts:
    0
    Joined:
    Nov 23, 2004
    Messages:
    2,347
    Mikl___,
    Code (ASM):
    1.  
    2. lea rdi, mass
    3. mov rax, 0d3d3d3d3d3d3d3d3h
    4. mov rcx, 256 / 8
    5. rep stosq
    6.  
     
    Entropy and Mikl___ like this.
  17. Entropy

    Entropy Member

    Blog Posts:
    0
    Joined:
    Aug 23, 2020
    Messages:
    185
  18. R81...

    R81... Active Member

    Blog Posts:
    0
    Joined:
    Feb 1, 2020
    Messages:
    166
    Конечно же rmn, но
    Code (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

    Blog Posts:
    0
    Joined:
    Nov 23, 2004
    Messages:
    2,347
    R81...,
    Ну, можно написать
    Code (ASM):
    1.  
    2. lea rdi, mass
    3. mov al, 0d3h
    4. mov rcx, 256
    5. rep stosb
    6.  
    если прям так памяти не хватает :) На глаз тут байт 18

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

    MaKsIm Active Member

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