rooaw 发表于 2021-1-7 14:47:40

《汇编语言》10.12寄存器冲突的问题(2)将所有字符串大写,有两个疑惑,寻求帮助

本帖最后由 rooaw 于 2021-1-7 14:51 编辑

整理了一下书上完整代码如下:

assume cs:code

data segment
      db 'word', 0
      db 'word', 0
      db 'word', 0
      db 'word', 0
data ends

code segment
start:
      mov ax, data
      mov ds, ax
      mov bx, 0                              ;ds:字符串地址

      mov cx, 4                              ;四组字符串
      s:      mov si, bx                     ;从第1个字符开始
                call capital                     ;capital用于将当前一组字符串改为大写
                add bx, 5                        ;到下一组字符串
                loop s

                mov ax, 4c00h
                int 21h

      capital:      push cx                     ;cx表示循环到了第几组
                        push si                        ;si表示当前组第几个字符

                        change:   mov cl,                                         ;字符存到cl
                                        mov ch, 0                                                
                                        jcxz ok                                             ;cx为0表示这组字符结束
                                        and byte ptr , 11011111b                ;否则字符转为大写
                                        inc si                                                ;到下一个字符
                                        jmp short change               

                        ok:         pop si                                          
                                        pop cx
                                        ret                                                   ;跳转到s循环里add bx, 5指令

code ends

end start


第一个疑惑是 si 寄存器为什么需要入栈(27行)?不管 pop si 后 si 的值为多少,都会回到循环开头被 bx 赋值(18行)不是吗?
第二个疑惑是 change 标号那段其实就是个循环,只是因为 cx 要被占用无法用来记循环次数,所以不好写成 loop,而是用的 jmp 转移?

wtchou 发表于 2021-1-7 16:31:15

问题1.
你说的没错, 在这程序中即使si不入栈也不会出错, 不过最好将子程序会用到的寄存器都事先保存, 以防止未来各种状况, 我猜作者是想表达这意思

问题2.
这里不用loop是因为要透过字符串后面的 '0' 来判断循环是否结束, 与cx是否被占用无关

jackz007 发表于 2021-1-7 17:18:26

本帖最后由 jackz007 于 2021-1-7 17:30 编辑

   assume ds:data , es:data , cs:code
stack segment stack para 'stack'
   dw 800h dup(00)
stack ends

data segment public para 'data'
    msg1db 'word' , 00
    msg2db 'word' , 00
    msg3db 'word' , 00
    msg4db 'word' , 00
data ends

code segment public para 'code'
captal proc near
      cmp al , 'a'
      jb cap01
      cmp al , 'z'
      ja cap01
      sub al , ' '
cap01:ret
captal endp

main proc far
      mov ax,data
      mov ds,ax
      mov es,ax
      mov bx,offset msg1 - 5
      mov cx,4
      cld
m1:   add bx,5
      mov si,bx
      mov di,bx
m2:   lodsb
      or al,al
      jz m3
      call captal
      stosb
      jmp m2
m3:   loop m1               
      mov ax,04c00h
      int 021h
main endp
code ends
end main

rooaw 发表于 2021-1-12 15:29:03

咦,最佳答案不小心给错了楼
页: [1]
查看完整版本: 《汇编语言》10.12寄存器冲突的问题(2)将所有字符串大写,有两个疑惑,寻求帮助