简体   繁体   中英

8-bit assembly programming, checking for palindrome

So, second question on here (This ones quite vague), one of the tasks that I have been given is to create something that checks for palindromes and then display Yes if it is and No if it isn't. My question is, how would you go about trying to make it? The only way I can think of to make it work is to go through the string, count the characters, half the total number in order to find the middle of the word, then increment by 1 and decrement by 1, then comparing the two characters to see if they're the same (Then Decrement by 2,3 and so on until you reach the end of the string.). Which i have tried to implement but have no idea how to do so.

So if anyone at all could give me any pointers at all that would be great, i will leave a link to the 8-bit simulator I'm using as well as what I have so far (Which is just the code to print YES/NO ATM.)

CODE:

JMP begin
input: DB "PALINDROMEEMORDNILAP"
DB 0
begin:
    MOV C, input    ;Points to var input
    MOV D, 232  ;Points to output
    CALL check  ;Skips to check
    HLT

check:


       ;This is where my method of checking whether it is or isn't a 
       ;palindrome would go

.NO:
    MOV C, NO   ; Points to var NO
    MOV A, [C]  ; Gets first char
    MOV [D], A  ; Write to output
    INC D  
    JMP .NO2

.NO2:
    MOV C, NO
    INC C       ; Increments the char that it is pointing to in var NO
    MOV A, [C]  ; Gets second char
    MOV [D], A  ; Write to output
    RET     ; Terminates

.YES:
    MOV C, YES  ;Points to var YES
    MOV A, [C]  ; Gets first char
    MOV [D], A  ; Puts 1st letter in output
    INC D       ; Increments D so it doesn't overwrite
    JMP .YES2

.YES2:
    MOV C, YES
    INC C       ; Increments the char that it is pointing to in var YES
    MOV A, [C]  ; Gets second char
    MOV [D], A  ; Puts 2nd letter in output
    INC D  
    JMP .YES3

.YES3:
    MOV C, YES
    INC C       ;Increments the char that it is pointing to in var YES
    INC C
    MOV A, [C]  ; Gets third char
    MOV [D], A  ; Puts 3rd letter in output
    RET     ; Terminates

YES: DB  "YES" ; Var for yes
NO:  DB "NO"  ; Var for no

LINK TO SIMULATOR: http://schweigi.github.io/assembler-simulator/

ANY help/pointers/advice would be amazing.

Thanks in advance!

Well, it looks like you probably missed how the example printing hello world works, and why they define zero byte at end of string. Which subsequently leads you to print it with fixed code (either 3 byte copy, or 2 byte copy).

Try a bit more to realize how that example "hello world" works, for example switch highlight of C and D to see how they are used as pointers into memory.

Try to read instruction description before executing it by "step", then try to guess how all the values will change, and run the "step". Then try to figure out any discrepancy, if you didn't guess it correctly, what was your mistake.


I modified the hello world plus your unfinished code and used a bit different constructs, so you can try to understand this one as next task (it will print "YES" as if input is palindrome, but it does no checking at all, it just sets fake "result" of check and follows with YES/NO output:

    MOV C, input    ;Points to var input
    CALL check  ; call check palindrome routine
    HLT

check:
    ; TODO palindrome check ... later ;)
    ; output: A = 0 when "NO", else "YES"

    MOV A, 123  ; fake result, try also "MOV A, 0"
    ; print result to output
    MOV D, 232  ; Points to output
    MOV C, YES  ; Point to string "YES"
    OR  A, A
    JNZ printYes ; when palindrome, C is correct
    ; print "NO" when not palindrome, modify C pointer
    MOV C, NO   ; Point to string "NO"
printYes:
    CALL print  ; reuse universal print subroutine to print YES/NO
    RET         ; exit check subroutine

print:      ; print(C:*from, D:*to), will print also last zero!
    PUSH A
.printLoop:
    MOV A, [C]  ; Get char from var
    MOV [D], A  ; Write char to output
    INC C       ; next source char
    INC D       ; next output cell
    OR  A, A    ; test if char is zero
    JNZ .printLoop
    POP A
    RET

; data defined after code, so I don't have to jump around them

YES: DB  "YES"
     DB  0
NO:  DB 78      ; ASCII 'N' in decimal
     DB 0x4F    ; ASCII 'O' in hexadecimal
     DB 0
input:
     DB "PALINDROMEEMORDNILAP"
     DB 0

label_to_see_length_of_code:

If you got all these, you should now be able to address particular letters in your input string, and do some tests upon them. So start by writing subroutine to calculate either length of string, or to return "pointer" to last character (ahead of zero terminator). Again debug, until it will work.

Then when you have this pointer, load other register with pointer to first character ( MOV <some spare register>,input ).

Then palindrome check algorithm can be like this:

    isPalindrome = 1
checkLoop:
    compare pointer to first char with pointer to last char
    => when (first_ptr >= last_ptr) jump to checkEnd
    load character from first_ptr
    load character from last_ptr
    inc  first_ptr
    dec  last_ptr
    compare two characters
    => when equal, loop to checkLoop
    isPalindrome = 0
checkEnd:

... hmm.. now I see you will run out of registers for this one... well, the remedy is simple for me, but I will let you to resolve it on your own, there are various strategies:

  • using memory as further storage, a bit slow to juggle around with loading/storing values into registers back and forth

  • optimizing the algorithm to needs less registers (it's possible to load only one character and compare it against memory from pointer, but then you have to make zero flag survive update of pointers, which is impossible in this order... but updating pointers first and then checking char would work, but that means the pointers already point to different char .. so can you make them point to correct char even when they are already updated?).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM