sub subtracts the second operand from the first operand and puts it in the first operand. Your first operand is a numeric constant (the address of the beginning of the array), nothing can be written there.- If you had a pointer to the end of the array in
esi , then it would be enough to swap the operands, and the size of the array would fall into esi . But since esi does not change in your code (operations like mov [esi+N], eax does not affect the value of esi , and should not affect it), this will not help you.
How would it work (but it would be pretty ugly):
lea esi, arr mov eax, 00 mov [esi], eax mov eax, 11 lea esi, [arr+1] mov [esi], eax mov eax, 22 lea esi, [arr+2] mov [esi], eax mov eax, 55 lea esi, [arr+14] mov [esi], eax add esi, 4 ; добавляем размер последнего добавленного элемента sub esi, offset arr ; из конца массива вычитаем начало, получаем размер
Also note that you write values from 32-bit registers into overlapping addresses. When you go through the array in ascending indexes, you simply have the next number to overwrite the last 3 bytes of the previous one. Because you have small numbers (fit in 1 byte), then you will not notice. But if you go through the array from the end to the beginning, then each next element that you record will erase 3 bytes after itself (which were written earlier). In this program, you just need to replace eax with al , since you have in fact an array of bytes.
How to correctly calculate the length of the array: you either know it in advance (in this case, you yourself indicated that the array size is 14 bytes), or if memory is allocated with a margin, and you, for example, read from a file, then you need a separate variable (in memory or case - as it is more convenient), where you will record how many elements were actually read. Before each reading we check that we will not go beyond the bounds of the array, after reading we increase the number of elements read by 1.