MOV BL, [strlen-1]
На самом деле это не то, что вы думаете.Это не хранит значение strlen - 1
в bl
.Скорее, он хранит значение по адресу strlen - 1
в bl
.
Если вы знаете C, это разница между:
byte* strlen = ...;
BL = *strlen - 1;
и:
byte* strlen = ...;
BL = *(strlen - 1);
В обозначениях сборки вы можете рассматривать скобки ([...]
) как означающие «адрес к разыменованию», где «адрес» взаимозаменяем с «местоположением в памяти»."- как указатель в C.
Если вы хотите вычесть 1 из фактического значения из strlen
, то вам нужно сначала загрузить значение в регистр, а затем вычесть1 из него.
В C:
byte* strlen = ...;
bl = *strlen;
bl -= 1;
В сборке:
movzx ebx, BYTE PTR [strlen]
sub ebx, 1 ; (or dec ebx)
Регистр BL
теперь будет содержать длину строки, минус 1Таким образом, вы можете сделать:
mov al, BYTE PTR [startOfString + ebx] ; al = startOfString[bl]
, чтобы загрузить последний символ в строке (начинающийся с адреса startOfString
) в переменную al
.
Затем следуйте за нимс:
cmp al, '.'
для установки флагов.Или, как у вас было изначально, вы можете использовать инструкцию в стиле CISC, которая объединяет нагрузку со сравнением:
cmp BYTE PTR [startOfString + ebx], '.'