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]
все означают одно и то же.