Как поместить значение из переменной в регистр? - PullRequest
0 голосов
/ 17 февраля 2019

Я хочу сравнить конечный символ моей строки с точкой.

Я посчитал длину строки и сохранил ее в переменной с именем strlen.поэтому я сделал cmp [string + strlen], '.'но это не сработало, поэтому я попытался перенести strlen в реестр, но это не сработало.программа вылетает.я использую 32-битную архитектуру Windows 10 x86

MOV BL, [strlen-1]      ;the length of the string minus 1 so i would end up 
                         in the last character of the string
cmp [string + BL], '.'
JE func1

1 Ответ

0 голосов
/ 17 февраля 2019
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], '.'
...