для небольшого задания мы должны сравнить строки, нам дали этот код в C
extern "C" {
bool isStringEqual(const char *s1, const char *s2);
}
static char *testStrings[] = {
"",
"Test String 1",
"Test String 2",
};
#define NUM_TEST_CASES (sizeof (testStrings) / sizeof (char *))
int main()
{
printf("CSIS\n\n");
for (int i = 0; i < NUM_TEST_CASES; i++) {
printf("Input string [%s] [%s] yields: %s\n ", testStrings[i], testStrings[i],
isStringEqual(testStrings[i], testStrings[i]) ? "true" : "false");
}
printf("Input string [%s] [%s] yields: %s\n ", testStrings[1], testStrings[2],
isStringEqual(testStrings[1], testStrings[2]) ? "true" : "false");
system("PAUSE");
return 0;
}
и мы должны написать ассемблер, который делает эту логику
; while (*s1 != 0 && *s2 != 0) {
; if (*s1 != *s2)
; return false;
; }
; return true
Раньше мы делали то, что сравнивали числа, которые были введены в C, а затем выполняли некоторые сравнения и вычисления в ассемблере. Это было хорошо, и я полностью их понял, у меня проблемы с пониманием заданного C и строк (они оба выглядят для меня как «i» или, возможно, 1 и 2 ??). И во-вторых, выяснить, как я могу сравнить две строки. Я понимаю, как работают прыжки и сравнения, и могу создавать циклы просто отлично, просто не знаю, как сравнивать строки...
Вот мой ассемблер, который запускается, но все равно распечатывает все как
вход
Input string [Test String 1] [Test String 1] yields: true
Input string [Test String 2] [Test String 2] yields: true
Input string [Test String 1] [Test String 2] yields: true
Press any key to continue . . .
Мой ассм:
isStringEqual PROC PUBLIC
PUSH ebp ; save caller base pointer
MOV ebp, esp ; set our base pointer
PUSH edi
PUSH esi
;--------------------------------------------------------
; while (*s1 != 0 && *s2 != 0) {
; if (*s1 != *s2)
; return false;
; }
; return true
;-----------------------------------------------------------
mov esi, [ebp+8] ;get s1
mov edi, [ebp+12] ;get s2
MOV ebx, 0 ;move 0 into ebx
str_cmp_loop:
MOV al, [esi + ebx] ;goes right to left for string
CMP al, [edi + ebx] ;compares
JNE str_ret_false
CMP al, 0
JE str_ret_true
INC ebx
JMP str_cmp_loop
str_ret_false:
PUSH eax
PUSH OFFSET fmt ; push the string format
ADD esp, (2 * 4) ; clear the stack
POP esi
POP edi
MOV esp, ebp ; deallocate locals
POP ebp ; restore caller base pointer
RET
str_ret_true:
PUSH eax
PUSH OFFSET fmt ; push the string format
ADD esp, (2 * 4) ; clear the stack
POP esi
POP edi
MOV esp, ebp ; deallocate locals
POP ebp ; restore caller base pointer
RET
isStringEqual ENDP ; end the procedure
END isStringEqual
Может кто-нибудь, пожалуйста, просто помогите мне, чтобы я мог пойти спать...
cmp
s подряд бессмысленно. Результаты второго переписывают первый. Как говорит Tommylee2k, вы сравниваете указатели, а не содержимое (cmp [eax], 0
). Вы увеличиваете указатель вeax
, но не вebx
. Там, вероятно, больше, но я бы начал с этого. - person David Wohlferd   schedule 24.03.2017while (*s1 != 0 && *s2 != 0) { if (*s1 != *s2) return false; }
- person AndersK   schedule 24.03.2017CMP esi
не разыменовывает больше, чемCMP eax
. Именно скобки (CMP [esi]
илиCMP [eax]
) указывают на то, что вы хотите, чтобы значение сохранялось по этому адресу. Кроме того, когда вы используетеJNE next
, вы говорите, что если esi не равно нулю (например, если это «A»), перейти к следующему. Вы уверены, что это то, что вы намереваетесь? «Далее» кажется выходом, а не продолжением. - person David Wohlferd   schedule 24.03.2017CMP esi,edi
все еще сравнивает указатели. вы должны прочитать память, на которую они указывают - person Tommylee2k   schedule 24.03.2017PUSH eax PUSH OFFSET fmt ADD esp, (2 * 4)
. Вы кладете 2 вещи только стопкой, а потом сразу их вытаскиваете? Как вы думаете, что это собирается сделать? - person David Wohlferd   schedule 24.03.2017