Reputation: 33
I'm trying to complete my last lab exercise for my microprocessors course and could really use some help with this. The job is to fill the commented empty lines with my own code. Here's the task:
**Task 2. Test if the string is a palindrome**
Modify the previous program so, that it checks whether the string is a palindrome. Complement the following program. Add the missing instructions.
include "emu8086.inc"
; START-OF-PROGRAM
org 100h
jmp start
; Memory variables:
msg3 db 0ah,0dh,"The string is a palindrome.",0
msg2 db 0ah,0dh,"The string is NOT a palindrome.",0
msg1 db "Enter a string (max 128 characters): ",0
; the buffer to save the entered string
mystr db 128 dup (0),0
mystrREV db 128 dup (0),0
endl db 0dh,0ah,0
length db 0
start: lea SI, msg1 ; Message address
CALL PRINT_STRING ; Print message from [SI]
; String mystring: Read string here!
; String max. length
; Read string into [DI]
lea si,endl
call print_string
; count the number of characters in the buffer mystr into CX:
mov cl,0 ; start from 0
lea SI,mystr ; Point SI to mystr
tess: mov al,[SI],0 ; End of data?
cmp al,0 ; -“-
je seur ; Proceed to next step
inc cl ; Increment data counter
inc SI ; Increment data pointer
jmp tess ; Check next
; copy mystr into mystrREV in reverse order
seur: mov length,cl ; Store # of characters in length
; Result buffer address into DI
; Source buffer address id SI(decremented)
coop: ; Copy character from source
; Copy character to destination
; Decrement source pointer
; Increment result pointer
; Decrement counter
; Take next if not done
; print both buffers
lea si,mystr
call print_string ; Print mystr
lea si,endl
call print_string ; Print cr+lf
lea si,mystrREV
call print_string ; Print mystrREV
lea si,endl
call print_string ;print cr+lf
; compare strings. If equal => palindrome
mov cl,length ; # of characters in buffers
lea si,mystr ; address of first buffer
lea di,mystrREV ; address of second buffer
niis: cmp cl,0 ; test if end-of-comparison/buffer
; jump to ok, palindrome/empty buffer
; Source buffer address
; Result buffer address
; Are same, still chance?
; Nop, jump to print NOT-message and exit
: increment source pointer
; increment destination pointer
; decrement counter
jmp niis ; Try next
positive: lea SI,msg3 ; Yess, palindrome
call PRINT_STRING ; Print it
jmp bort ; and exit
negative: lea si,msg2 ; NOT a palindrome
call PRINT_STRING ; Print it and exit
bort: mov ax,4c00h ; code for return to ms-dos
int 21h ; call ms-dos terminate program
ret
; Macro definitions
DEFINE_GET_STRING
DEFINE_PRINT_STRING
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS
end ;END-OF-PROGRAM
My program only prints the first letter of the input string as reversed string and doesn't really test the palindrome properly. This is what I've done so far:
include "emu8086.inc"
; START-OF-PROGRAM
org 100h
jmp start
; Memory variables:
msg3 db 0ah,0dh,"The string is a palindrome.",0
msg2 db 0ah,0dh,"The string is NOT a palindrome.",0
msg1 db "Enter a string (max 128 characters): ",0
; The buffer to save the entered string
mystr db 128 dup (0),0
mystrREV db 128 dup (0),0
endl db 0dh,0ah,0
length db 0
start: lea SI, msg1 ; Message msg1 address
CALL PRINT_STRING ; Print message from [SI]
; *********************** My code starts *********************
lea di, mystr ; String mystring: Read string here!
mov dx, 128 ; String max. length
call get_string ; Read string into [DI]
; *********************** My code ends ***********************
lea si,endl ; String endl
call print_string ; Print endl
; count the number of characters in the buffer mystr into CX:
mov cl,0 ; start from 0
lea SI,mystr ; Point SI to mystr
tess: mov al,[SI],0 ; End of data?
cmp al,0 ; -"-
je seur ; Proceed to next step
inc cl ; Increment data counter
inc SI ; Increment data pointer
jmp tess ; Check next
; copy mystr into mystrREV in reverse order
seur: mov length,cl ; Store # of characters in length
; *********************** My code starts *********************
; Something goes wrong in this code block
lea di, mystrREV ; Result buffer address into DI
lea si, mystr ; Source buffer address id SI(decremented)
coop:mov al, [si] ; Copy character from source
mov [di], al ; Copy character to destination
dec si ; Decrement source pointer
inc di ; Increment result pointer
dec cl ; Decrement counter
cmp cl,0 ; Take next if not done
jne coop
; *********************** My code ends ***********************
; print both buffers
lea si,mystr
call print_string ; Print mystr
lea si,endl
call print_string ; Print cr+lf
lea si,mystrREV
call print_string ; Print mystrREV
lea si,endl ; CODE DOESN'T PRINT ENOUGH
call print_string ;print cr+lf
; compare strings. If equal => palindrome
mov cl,length ; # of characters in buffers
lea si,mystr ; address of first buffer
lea di,mystrREV ; address of second buffer
niis: cmp cl,0 ; test if end-of-comparison/buffer
; *********************** My code starts *********************
je positive ; jump to ok, palindrome/empty buffer
lea si,mystr ; Source buffer address
lea di,mystrREV ; Result buffer address
cmp di,si ; Are same, still chance?
jne negative ; Nop, jump to print NOT-message and exit
inc si ; increment source pointer
inc di ; increment destination pointer
dec cl ; decrement counter
; *********************** My code ends ***********************
jmp niis ; Try next
positive: lea si,msg3 ; Yess, palindrome
call PRINT_STRING ; Print it
jmp bort ; and exit
negative: lea si,msg2 ; NOT a palindrome
call PRINT_STRING ; Print it and exit
bort: mov ax,4c00h ; code for return to ms-dos
int 21h ; call ms-dos terminate program
ret
; Macro definitions
DEFINE_GET_STRING
DEFINE_PRINT_STRING
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS
end ;END-OF-PROGRAM
My result:
Enter a string (max 128 characters): abba
abba
a
The string is NOT a palindrome.
Expected result:
Enter a string (max 128 characters): innostunutsonni
innostunutsonni
innostunutsonni
The string is a palindrome.
We're using this old emulator software called emu8086 which has some documentation online. Any help would be highly appreciated! Thank you.
Upvotes: 3
Views: 2629
Reputation: 39166
; *********************** My code starts ********************* ; Something goes wrong in this code block lea di, mystrREV ; Result buffer address into DI lea si, mystr ; Source buffer address id SI(decremented) coop: mov al, [si] ; Copy character from source mov [di], al ; Copy character to destination dec si ; Decrement source pointer inc di ; Increment result pointer dec cl ; Decrement counter cmp cl,0 ; Take next if not done jne coop ; *********************** My code ends **********************
You should have taken the hint in the comment "; Source buffer address id SI(decremented)".
In order to traverse the source string backwards - that's what 'decremented' means - you need to initialize the source pointer SI
to the end of the string. That means that you need to compute StartOfString + LengthOfString - 1.
; *********************** My code starts *********************
lea di, mystrREV ; Result buffer address into DI
lea bx, mystr ; Source buffer address id SI(decremented)
add bl, cl
adc bh, 0
lea si, [bx-1]
coop:
mov al, [si] ; Copy character from source
mov [di], al ; Copy character to destination
dec si ; Decrement source pointer
inc di ; Increment result pointer
dec cl ; Decrement counter
jne coop ; Take next if not done
; *********************** My code ends **********************
Please notice that you don't need that cmp cl,0
instruction because the preceding dec cl
instruction already set the necessary flags.
; compare strings. If equal => palindrome mov cl,length ; # of characters in buffers lea si,mystr ; address of first buffer lea di,mystrREV ; address of second buffer niis: cmp cl,0 ; test if end-of-comparison/buffer ; *********************** My code starts ********************* je positive ; jump to ok, palindrome/empty buffer lea si,mystr ; Source buffer address lea di,mystrREV ; Result buffer address cmp di,si ; Are same, still chance? jne negative ; Nop, jump to print NOT-message and exit inc si ; increment source pointer inc di ; increment destination pointer dec cl ; decrement counter ; *********************** My code ends ***********************
Your code to compare the strings does not compare at all! The comments they gave are misleading.
You don't want the addresses again in SI
and DI
. You need to fetch the characters that this registers point at and then compare those:
; *********************** My code starts *********************
je positive
mov al, [si] ; Source buffer address <<<<< misleading comment
mov dl, [di] ; Result buffer address <<<<< misleading comment
cmp al, dl ; Are same, still chance?
jne negative
Upvotes: 1
Reputation: 5775
You set SI to point to the first byte of mystr
and after copying this byte you decrement SI, which gets SI out of the buffer. SI should be pointed to the last character in mystr
in the beginning. Instead of
; Something goes wrong in this code block
lea di, mystrREV ; Result buffer address into DI
lea si, mystr ; Source buffer address id SI(decremented)
coop:mov al, [si] ; Copy character from source
mov [di], al ; Copy character to destination
dec si ; Decrement source pointer
try this:
lea di, mystrREV ; Result buffer address into DI
lea si, mystr ; Source buffer address id SI(decremented)
movzx cx,[length] ; Let cx be the size of mystr.
add si,cx ; Let si point behind mystr.
dec si ; Let si point to the last character of mystr.
coop:mov al, [si] ; Copy character from source
mov [di], al ; Copy character to destination
dec si ; Decrement source pointer
Instruction LEA in most assemblers including MASM requires (or at least tolerates) the second operand be in brackets, e.g. LEA DI,[mystrREV], you should accustom to this syntax.
The instruction tess: mov al,[SI],0 ; End of data?
looks weird, are you sure it doesn't trigger an error?
Instead of posting images on SO its better to copy&paste the text from console, so it is included in your question and stays visible even when imgur.com cesases its existence.
Posting the source text is not enough, it should be accompanied with information how it was assembled and linked.
Upvotes: 2