assembly - x86 程序集 : Output from swap function is incorrect even when the implementation is correct

标签 assembly swap x86-16

我一直在研究交换函数,以便最终使用 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个字节的空间,所以参数应该在12和14位置。

谢谢:D

编辑:问题是我使用的是 8 位寄存器的 16 位寄存器实例( AX 和 CX 的 AH 和 CL 实例),我还忘记在函数开始时设置 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
<小时/>

另一个注意事项:堆栈帧变量的 param1swap1swap2 equ 可以更接近定义使用它们的函数的位置。这将更容易验证它们是否正确。

关于assembly - x86 程序集 : Output from swap function is incorrect even when the implementation is correct,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59125529/

相关文章:

assembly - 访问 PIT (?) IO 端口 44h 和 46h - 这些端口有什么作用?

c++ - GMP 如何在任意数量的字节上存储它的整数?

assembly - 替换 INT 9 ISR 时崩溃,但链接到它时不会崩溃

将 C 程序转换为内联汇编?

php - 如何将链接文本交换为链接,将YouTube链接交换为在YouTube中将代码嵌入YouTube

c++ - std::vector::swap 是如何实现的?

c# - 如何交换两个数字并找到结果中较大的一个?

assembly - 与推送功能相同的指令序列

c - x86 程序集 : Using #define'd constants as arguments in calls to to #define's macros

c - ARM - 加载和存储汇编指令