我正在尝试完成我的微处理器课程的上一个实验练习,可以为此提供一些帮助。工作是用我自己的代码填充注释的空行。这是任务:
**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
我的程序仅将输入字符串的第一个字母打印为反向字符串,并没有真正测试回文。这是我到目前为止所做的:
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
我的结果:
Enter a string (max 128 characters): abba
abba
a
The string is NOT a palindrome.
预期结果:
Enter a string (max 128 characters): innostunutsonni
innostunutsonni
innostunutsonni
The string is a palindrome.
我们正在使用名为emu8086的旧仿真器软件,该软件在线提供了一些文档。任何帮助将不胜感激!谢谢。
您将SI设置为指向mystr
的第一个字节,并在复制此字节后递减SI,这会将SI从缓冲区中移出。 SI应该指向mystr
开头的最后一个字符。代替
; 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
尝试一下:
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
在包括MASM在内的大多数汇编程序中,指令LEA]要求(或至少允许)第二个操作数放在方括号中,例如LEA DI,[mystrREV],您应该习惯这种语法。
tess: mov al,[SI],0 ; End of data?
指令看起来很奇怪,您确定它不会触发错误吗?
与其在SO上发布图像,不如从控制台复制并粘贴文本,所以它包含在您的问题中,即使imgur.com停止存在它也保持可见。
发布源文本是不够的,应该附带有关其组装和链接方式的信息。
; *********************** 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 **********************
您应该已经在注释“ ;;源缓冲区地址ID SI(decremented)”中使用了提示。
为了向后遍历源字符串-这就是'减少'的含义-您需要将源指针SI
初始化为字符串的末尾。这意味着您需要计算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 **********************
请注意,您不需要该cmp cl,0
指令,因为前面的dec cl
指令已经设置了必要的标志。
; 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 ***********************
您用于比较字符串的代码根本不进行比较!他们的评论令人误解。
您不再需要SI
和DI
中的地址。您需要获取此寄存器指向的字符,然后进行比较:
; *********************** 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