I'm trying to write an assembly program that compares two strings and outputs whether they're equal or not, I've tried to do this by increasing the index register one by one and comparing the characters.
But there seems to be a mistake in my code since I was expecting the output Equal
But the actual output was:
Equal
NotEqual
Code:
%include "asm_io.inc"
segment .data
str1: db "ThisIsSomeString", 0
str2: db "ThisIsSomeString", 0
msg_eq: db "Equal", 10, 0
msg_neq: db "NotEqual", 10, 0
segment .text
global asm_main
asm_main:
mov esi, str1
mov edi, str2
xor edx, edx ; to clear edx for index addressing
loop:
mov al, [esi + edx]
mov bl, [edi + edx]
inc edx
cmp al, bl
jne not_equal
cmp al, 0 ; check if we're at the end of string
je equal
jmp loop
not_equal:
mov eax, 4 ; system call number (sys_write = 4)
mov ebx, 1 ; stdout = 1
mov ecx, msg_neq ; message to print
int 0x80 ; issue a system call
jmp exit
equal:
mov eax, 4
mov ebx, 1
mov ecx, msg_eq
int 0x80
jmp exit
exit:
mov eax, 1 ; system call number (sys_exit = 1)
mov ebx, 0 ; exit code
int 0x80
You are not providing a length to sys_write
. It takes the number of bytes to write in edx
. It does not care that the string you are attempting to print is a nul-terminated string. You can solve the problem by saving the length of the messages you wish to output, e.g.
segment .data
str1: db "ThisIsSomeString", 0
str2: db "ThisIsSomeString", 0
msg_eq: db "Equal", 10, 0
len_eq equ $ - msg_eq
msg_neq: db "NotEqual", 10, 0
len_neq equ $ - msg_neq
In nasm
the $
is the present stack address immediately before the current statement. So simply using $ - string_before
where you declare your strings, you are able to save the length for later use with sys_write
, e.g.
segment .data
str1: db "ThisIsSomeString", 0
str2: db "ThisIsSomeString", 0
msg_eq: db "Equal", 10, 0
len_eq equ $ - msg_eq
msg_neq: db "NotEqual", 10, 0
len_neq equ $ - msg_neq
segment .text
global _start
_start:
mov esi, str1
mov edi, str2
xor edx, edx ; to clear edx for index addressing
loop:
mov al, [esi + edx]
mov bl, [edi + edx]
inc edx
cmp al, bl
jne not_equal
cmp al, 0 ; check if we're at the end of string
je equal
jmp loop
not_equal:
mov eax, 4 ; system call number (sys_write = 4)
mov ebx, 1 ; stdout = 1
mov ecx, msg_neq ; message to print
mov edx, len_neq ; length in edx
int 0x80 ; issue a system call
jmp exit
equal:
mov eax, 4
mov ebx, 1
mov ecx, msg_eq
mov edx, len_eq ; length in edx
int 0x80
jmp exit
exit:
mov eax, 1 ; system call number (sys_exit = 1)
mov ebx, 0 ; exit code
int 0x80
(note: your %include "asm_io.inc"
statement is not needed)
Also note, I have replaced your asm_main
with _start
to compile and run on my box, just change it back as needed.
Example Output
$ ./bin/strcmp32
Equal