GNU Assembler не может сравнить строку с двумя переменными

Я не могу сравнить строку с двумя переменными в ассемблере GNU

   mov $[name], %eax            # move name into eax
   mov $[constname], %ebx       # move constname into ebx
   cmp %eax, %ebx               # compare two operands
   je if                        # if
   call else                    # else

1 ответ

Язык ассемблера немного отличается от всех других языков, поэтому все работает не так, как вы привыкли на других языках. Например, вы можете сделать это на C++ или многих других языках:

string s = "hello"
string d = "hello"
if (s == d) {}

В сборке вы не можете сделать это, потому что у вас нет таких хороших абстракций, с которыми вы могли бы работать. Вы находитесь рядом с тренажером, поэтому большую часть тяжелой работы вам придется делать самостоятельно.

Ваш код не работает по нескольким причинам

   mov $[name], %eax            # move name into eax

Выше инструкции переместит адрес изname в %eax. Итак, потом, когда вы это сделаете:

cmp %eax, %ebx

Он сравнивает два адреса, а не "значения".

Если бы мы, например, хотели mov "значение" наших строк в регистры, мы запишем:

mov name, %eax

Здесь важно то, что %eaxможет содержать только 32-битные (4 байта) данных. Итак, если ваша строка была "Привет",%eaxбудет содержать только 4 байта "olle". Обратный порядок следования байтов. Это сильно ограничивает нас, но у нас есть другие способы обойти это.

Мы можем использовать cmpsbпри условии, что у нас есть минимальная длина для работы.

#our strings
.data
  name:      .string "Hello"
  constname: .string "Hello"

# other instructions...

   mov $(name), %edi            # move the "Address" of name into edi
   mov $(constname), %esi       # move "Address" of constname into esi
   mov $5, %ecx                 # compare 5 characters only, you can use string1 length here

   rep cmpsb                    # rep `cmpsb` (Compare String Byte), till %ecx is 0
   jz  if                       # Success, jump to if label if zero flag is set
   call else                    # Strings were not equal
# other stuff...

if:                          # if label


Примечание:

Я очень рекомендую вам использовать $(..) синтаксис вместо $[...]. Синтаксис AT&T уже пронизан синтаксическими сложностями, поэтому давайте остановимся на наиболее часто используемом. Например$name, $(name) а также $[name] все означают одно и то же.

Другие вопросы по тегам