【问题标题】:I can't figure out how to print arrays and in turn, I can't figure out how to swap elements in an array我不知道如何打印数组,反过来,我也不知道如何交换数组中的元素
【发布时间】:2025-11-27 16:30:01
【问题描述】:

这是 c++ 文件:

#include <iostream>
using namespace std;

//This is the C prototype of the assembly function, it requires extern"C" to
//show the name is going to be decorated as _test and not the C++ way of
//doing things
extern"C"
{
    //char arrayReverse(char*, int);
    int numChars(char *, int);
    char swapChars(char *, int);
}

int main()
{
    const int SIZE = 7;
    char arr[SIZE] = { 'h', 'e', 'l', 'l', 'o', '1', '2' };

    int val1 = numChars(arr, SIZE);
    cout << "The number of elements is: " << val1 << endl;

    char val2 = swapChars(arr, SIZE);
    cout << "Swapped! " << endl;


    return 0;
}

还有我的 swapChars() 文件:

    .686
    .model flat
    .code

    _swapChars PROC ; named _test because C automatically prepends an underscode, it is needed to interoperate
        push ebp
        mov ebp,esp ; stack pointer to ebp

        mov ebx,[ebp+8] ; address of first array element
        mov ecx,[ebp+12] ; number of elements in array
        mov ebp,0
        mov eax,0
        mov edx,ebx     ;move first to edx
        add edx, 7      ;last element in the array

    loopMe:
        cmp ebp, ecx        ;comparing iterator to total elements
        jge nextLoopMe
        mov eax, [ebx]      ;move 1st element into tmp eax
        mov ebx, [edx]      ;move last element into first
        mov edx, eax        ;move tmp into last
        push ebx            ;push first element onto stack
        add ebx, 1          ;first + 1
        sub edx, 1          ;last - 1
        add ebp, 1          ;increment
    jmp loopMe




        nextLoopMe:
            mov ebx,[ebp+8] ;find first element again  USING AS FFRAME POINTER AGAIN
            cmp ebx, ecx    ;comparing first element to number of elements
            je allDone

            pop ebx
            add ebx, 1
        jmp nextLoopMe

    allDone:    
        pop ebp
        ret
    _swapChars ENDP

    END 

这应该取 arr[0] 中的值并将其与 arr[6]、arr[1] 与 arr[5] 等交换,直到整个数组被交换然后显示它。我不知道我写的任何代码是否能做任何我想做的事情,但我正在寻找一种方法来看看发生了什么。

有没有一种方法可以让 asm 代码在遍历循环时将内容打印到控制台?

寄存器 ( [ebx] ) 周围的括号是否表示寄存器的值?

在loopMe:中时,第三行

mov eax, [ebx]

我得到一个异常“在 assignment4.exe 中的 0x012125FC 抛出异常:0xC0000005:访问冲突读取位置 0xCCCCCCCD。”

我是否正确处理掉期?

感谢您的宝贵时间。

【问题讨论】:

  • 使用调试器单步调试代码。 [ebx] 是地址 ebx 的内存访问 - 如果您遇到异常,则意味着 ebx 不指向有效内存。您还应该阅读有关调用约定的信息,必须保留一些寄存器(包括ebx)。将ebp 归零似乎也不是一个好主意,尤其是当您以后想将其用作指针时。
  • 你到底为什么要在汇编程序中实现这些功能??
  • 肯定是学校作业什么的。其实这些都是很好的学习经验,恕我直言。
  • 所以,现在我无法将寄存器的值显示到控制台。我能做什么?

标签: c++ arrays assembly swap masm


【解决方案1】:

您确实需要学习使用调试器来逐步完成此操作。也就是说,这是我看到的一些问题。

add edx,7

会将 edx 指向数组的末尾。就像 C 代码中的 arr[7] 一样。应该是add edx,6 将edx 指向最后一个字符。

在您的 proc 中间更改 ebp 很容易出错,我认为您那里有错误。您更改它的值,但随后期望 [ebp+8] 稍后引用相同的数据。

您也没有正确修改列表。要将字符从一个元素移动到另一个元素,您可以执行以下操作:

mov al, [ebx]     ; copy byte from address ebx to register al
mov [edx], al     ; copy byte in register al into address edx

eax 寄存器是 32 位的,一次复制 4 个字节,而不是 1 个。

【讨论】:

  • @drnips :如果此答案有用并解决了您的问题,请考虑接受它作为答案。有关接受答案的方式和原因的更多信息,请访问here
【解决方案2】:

首先,您的代码不安全,因为您忘记在 char 数组的末尾添加 \0。当您使用函数来处理您的 char 或 char 字符串时,它会引发内存泄漏。大小应为 8,数组中的最后一个应为 \0。

【讨论】:

  • 数组不必以零结尾,也不会导致内存泄漏。