【问题标题】:Palindrome program for emu8086 in assembly language汇编语言中emu8086的回文程序
【发布时间】:2020-04-26 14:10:26
【问题描述】:

我正在尝试完成我的微处理器课程的最后一个实验室练习,我真的需要一些帮助。 工作是用我自己的代码填充注释的空行。 任务如下:

**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.

Console view

预期结果:

Enter a string (max 128 characters): innostunutsonni
innostunutsonni
innostunutsonni

The string is a palindrome.

Console view

我们正在使用这个名为 emu8086 的旧模拟器软件,它有一些在线文档。 任何帮助将不胜感激!谢谢。

【问题讨论】:

    标签: assembly palindrome emu8086


    【解决方案1】:

    您将 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
    

    指令 LEA 在包括 MASM 在内的大多数汇编程序中都要求(或至少允许)第二个操作数放在括号中,例如LEA DI,[mystrREV],你应该习惯这种语法。

    指令tess: mov al,[SI],0 ; End of data?看起来很奇怪,你确定它不会触发错误吗?

    与其在 SO 上发布图像,不如从控制台复制和粘贴文本,这样它就会包含在您的问题中,并且即使 imgur.com 停止存在也仍然可见。

    仅发布源文本是不够的,还应附上如何组合和链接的信息。

    【讨论】:

    • 您好,感谢您的帮助!我更新了我的帖子并尝试了你的说明,但他们产生了一个错误,因为 emu8086 显然没有 movzx 指令。错误是(45) illegal instruction: movzx cx,[length] or wrong parameters. 我们在课程中使用的软件绝不是最佳的。这条线tess: mov al,[SI],0 ; End of data? 是练习的一部分,所以应该没问题。
    • 然后你可以用另外两条指令替换movzx cx,[length]mov ch,0mov cl,[length](或者可能是mov cl,length)。对不起,Erik,你必须用这么糟糕的模拟器学习汇编语言......
    • 是的,这似乎在 emu8086 中有效。我现在完成了程序,再次感谢。希望学校将来能升级课程!
    【解决方案2】:

    问题 1(改进)

    ; *********************** 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 指令已经设置了必要的标志。

    问题 2(新)

    ; 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 ***********************
    

    您用于比较字符串的代码根本不进行比较!他们给出的 cmets 具有误导性。

    您不想再使用SIDI 中的地址。您需要获取此寄存器指向的字符,然后进行比较:

    ; *********************** 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
    

    【讨论】:

    • 谢谢你,这非常有帮助!我让程序现在可以运行了。
    猜你喜欢
    • 2015-04-24
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    相关资源
    最近更新 更多