toshiba7987 发表于 2025-8-20 16:46:57

提问

file:///C:/Users/19798/OneDrive/%E6%A1%8C%E9%9D%A2/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202025-08-20%20024155.png,这个代码里是不是没有把cx入栈

FishC 发表于 2025-8-20 16:47:42

你好!很抱歉,我无法直接查看你本地文件的截图链接。

不过,根据你的问题“这个代码里是不是没有把cx入栈”来推断,你很可能是在分析一段汇编语言代码。

在x86汇编中,CX 寄存器属于调用者保存(Caller-Saved)的寄存器,也叫易失性寄存器。

这意味着:

[*]当一个函数(或过程)被调用时,它可以随意修改CX寄存器的值而无需恢复。
[*]因此,是调用者(Caller)的责任,如果它希望在函数调用后CX的值还和调用前一样,那么它必须在调用指令(如 CALL)之前,自己手动将CX的值压栈(PUSH CX)保存起来,并在调用结束后再弹出(POP CX)恢复。


所以,如果你的代码是“调用者”部分的代码,并且在调用一个函数后还需要使用原来的CX值,那么它确实需要把CX入栈。

如果你的代码是“被调用者”(函数内部)的代码,那么按照约定,它不需要保存和恢复CX(除非函数内部为了某些临时用途自己想保存,但那不是约定强制的)。

一个标准的保存与恢复流程看起来是这样的:


; ... 一些代码 ...
MOV CX, 100h      ; 给CX赋值一个重要的值

PUSH CX         ; 调用者在CALL之前保存CX
CALL SomeFunction ; 调用某个函数
POP CX            ; 调用者在CALL之后恢复CX

; 此时CX的值又变回了100h,可以安全使用了
; ... 后续代码 ...


总结一下:问题很可能出在“调用者”没有履行它的职责去保存CX,而不是“被调用者”忘了做这件事。

希望这个解释能帮你定位到问题!如果情况更复杂,欢迎你直接把相关代码贴出来(用标签),我们可以再一起分析。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

不二如是 发表于 2025-8-20 17:37:49

代码发下,才知道cx入栈哦

出现 push cx、pusha(16位)或在 MASM/TASM 的 PROC USES cx--》就是有保存。

只看到 push ax/bx/dx,没有 push cx、也没有 USES cx、也没有 pusha--》就是没保存。

toshiba7987 发表于 2025-8-20 19:52:34

assume cs:code

data segment
   db 'woed',0
       db 'unix',0
       db 'wind',0
       db 'good',0
data ends

code segment
start:   mov ax,data
         mov ds,ax
                   mov bx,0
                  
                   mov cx,4
                s: mov si,bx
                   call capital
                   add bx,5
                   loop s
                  
                   mov ax,4c00h
                   int 21h

capital: mov cl,
         mov ch,0
               jcxz ok
               and byte ptr,11011111b
               inc si
               jmp short capital
        ok:ret
code ends
end start

toshiba7987 发表于 2025-8-20 20:09:35

如果不push cx,就起不到循环4次的效果,它在下面的capital部分值已经被修改为0了
页: [1]
查看完整版本: 提问