x86 程序集:即使实现正确,交换函数的输出也不正确
x86 assembly: Output from swap function is incorrect even when the implementation is correct
我一直在研究交换函数,以便最终使用 x86 程序集实现冒泡排序。
我的代码还包括一个函数,该函数稍后为另一个函数重构给定数字(从 - 到 + ,反之亦然),我在测试交换函数之前调用了该函数
这是目前的代码:
org 100h
jmp main
numToNeg dw -9
toSwap1 db 'a'
toSwap2 db 'b'
param1 equ 8
swap1 equ 12
swap2 equ 14
main:
push offset numToNeg
call refactor
mov ax, numToNeg
call print_num
PRINTN
PRINTN "Before Swap:"
mov al, toSwap1
Call print_al_chr ;This function prints the given char inside al
mov al, toSwap2
Call print_al_chr
push offset toSwap1
push offset toSwap2
call swap
PRINTN
PRINTN "After Swap:"
mov al, toSwap1
Call print_al_chr
mov al, toSwap2
Call print_al_chr
PROC refactor
push bp
push bx
push ax
mov bp, sp
mov bx, [bp + param1]
mov ax, [bx]
not ax
inc ax
mov [bx], ax
pop ax
pop bx
pop bp
retn 2
ENDP refactor
PROC swap
push bp
push ax
push cx
push bx
push di
mov di, [bp + swap1]
mov ax, [di]
mov bx, [bp + swap2]
mov cx, [bx]
mov [bx], ax
mov [di], cx
pop di
pop bx
pop cx
pop ax
pop bp
retn 4
ENDP swap
现在我 100% 确定交换函数是正确的,所以问题出在我的主要函数中,但我自己无法弄清楚。当我调试代码时,堆栈对我来说看起来不错,但我现在很困惑:/
需要说明的是,函数 "print_al_chr" 确实有效,并且实现在我每次导入的另一个文件中。一开始我认为问题可能出在我一开始使用的 'equ' 上,但我很确定我传递的值确实是正确的,因为在我推送的函数中5个寄存器,总共占用10个字节space,所以参数应该在12和14的位置。
谢谢 :D
编辑:问题是我使用的是 8 位寄存器的 16 位寄存器(AX 和 CX 的 AH 和 CL Instant),我也忘记了在函数开始时设置 BP,就像我在重构功能。感谢大家的耐心和帮助 :D
您在此函数中缺少 mov bp, sp
:
PROC swap
push bp
push ax
push cx
push bx
push di
mov di, [bp + swap1]
您为每个变量保留了一个字节:
toSwap1 db 'a'
toSwap2 db 'b'
但后来您使用了 16 位字加载和存储:
mov di, [bp + swap1]
mov ax, [di]
mov bx, [bp + swap2]
mov cx, [bx]
mov [bx], ax
mov [di], cx
因为 di
会指向 toSwap1,我在这里引用的最后一条指令会覆盖这两个变量。 (如果您正确设置了 bp
,就会发生这种情况。)
您在 main 函数末尾缺少程序终止调用:
main:
push offset numToNeg
call refactor
[...]
mov al, toSwap2
Call print_al_chr
PROC refactor
如果这确实适用于 86-DOS 兼容系统,您应该在最后一次调用 print_al_chr 后添加以下内容:
mov ax, 4C00h
int 21h
另注:param1、swap1和swap2 equ
用于堆栈帧变量的 可能更接近于定义使用它们的这些函数的位置。这样可以更容易地验证它们是否正确。
我一直在研究交换函数,以便最终使用 x86 程序集实现冒泡排序。
我的代码还包括一个函数,该函数稍后为另一个函数重构给定数字(从 - 到 + ,反之亦然),我在测试交换函数之前调用了该函数
这是目前的代码:
org 100h
jmp main
numToNeg dw -9
toSwap1 db 'a'
toSwap2 db 'b'
param1 equ 8
swap1 equ 12
swap2 equ 14
main:
push offset numToNeg
call refactor
mov ax, numToNeg
call print_num
PRINTN
PRINTN "Before Swap:"
mov al, toSwap1
Call print_al_chr ;This function prints the given char inside al
mov al, toSwap2
Call print_al_chr
push offset toSwap1
push offset toSwap2
call swap
PRINTN
PRINTN "After Swap:"
mov al, toSwap1
Call print_al_chr
mov al, toSwap2
Call print_al_chr
PROC refactor
push bp
push bx
push ax
mov bp, sp
mov bx, [bp + param1]
mov ax, [bx]
not ax
inc ax
mov [bx], ax
pop ax
pop bx
pop bp
retn 2
ENDP refactor
PROC swap
push bp
push ax
push cx
push bx
push di
mov di, [bp + swap1]
mov ax, [di]
mov bx, [bp + swap2]
mov cx, [bx]
mov [bx], ax
mov [di], cx
pop di
pop bx
pop cx
pop ax
pop bp
retn 4
ENDP swap
现在我 100% 确定交换函数是正确的,所以问题出在我的主要函数中,但我自己无法弄清楚。当我调试代码时,堆栈对我来说看起来不错,但我现在很困惑:/
需要说明的是,函数 "print_al_chr" 确实有效,并且实现在我每次导入的另一个文件中。一开始我认为问题可能出在我一开始使用的 'equ' 上,但我很确定我传递的值确实是正确的,因为在我推送的函数中5个寄存器,总共占用10个字节space,所以参数应该在12和14的位置。
谢谢 :D
编辑:问题是我使用的是 8 位寄存器的 16 位寄存器(AX 和 CX 的 AH 和 CL Instant),我也忘记了在函数开始时设置 BP,就像我在重构功能。感谢大家的耐心和帮助 :D
您在此函数中缺少 mov bp, sp
:
PROC swap
push bp
push ax
push cx
push bx
push di
mov di, [bp + swap1]
您为每个变量保留了一个字节:
toSwap1 db 'a'
toSwap2 db 'b'
但后来您使用了 16 位字加载和存储:
mov di, [bp + swap1]
mov ax, [di]
mov bx, [bp + swap2]
mov cx, [bx]
mov [bx], ax
mov [di], cx
因为 di
会指向 toSwap1,我在这里引用的最后一条指令会覆盖这两个变量。 (如果您正确设置了 bp
,就会发生这种情况。)
您在 main 函数末尾缺少程序终止调用:
main:
push offset numToNeg
call refactor
[...]
mov al, toSwap2
Call print_al_chr
PROC refactor
如果这确实适用于 86-DOS 兼容系统,您应该在最后一次调用 print_al_chr 后添加以下内容:
mov ax, 4C00h
int 21h
另注:param1、swap1和swap2 equ
用于堆栈帧变量的 可能更接近于定义使用它们的这些函数的位置。这样可以更容易地验证它们是否正确。