从 C++ 访问汇编语言

发布于 2024-12-14 09:48:49 字数 2176 浏览 3 评论 0原文

这是我的编程作业。我需要使用 8086 编程语言编写的方法找出整数数组中最大的一个。这是我的尝试:

  #include <iostream.h>
    #include <conio.h>

    int returnLargest(int a[])
    {
        int max;
        asm mov si,offset a

        for(int i=0;i<6;i++) //Assuming six numbers in the array...Can be set to a variable 'n' later
        {
              asm mov ax,[si]
              asm mov max,ax
              asm inc si
              cout<<max<<"\n";    //Just to see what is there in the memory location
        }

        asm mov si,offset a
        asm mov cx,0000h

        asm  mov dx, [si]

            asm mov cx,06h

        skip: asm   mov si,offset a
        asm mov bx,[si]
        asm        mov max,bx
        asm inc si
        abc: asm   mov bx,max
           asm     cmp [si],bx
        asm jl ok
           asm     mov bx,[si]
              asm  mov max,bx
        ok: asm loop abc
        asm mov ax,max
        return max;
    }
    void main()
    {
        clrscr();
        int n;
        int a[]={1,2,3,4,5,6};
        n=returnLargest(a);
        cout<<n; //Prints the largest
        getch();
    }

预期答案是

1 2 3 4 5 6 6. 但我得到的是这样的: 在此处输入图像描述

在这里我坐下来想......不是吗数组索引 i 处的值实际存储在内存中?因为至少我们被告知,如果 a[i] 是 12(比如说),那么第 i 个内存位置就会在其中写入数字 12。

或者,如果该值未存储在内存位置,我如何写入内存位置以完成所需的任务?

我还请求大家链接一些网络/平装本上的材料,以便温习这些概念。

编辑:

汇编中的相同代码工作得很好......

data segment
    a   db  01h,02h,03h,04h,05h,06h,'$'
    max db  ?
data ends

code segment
    start:
        assume cs:code,ds:data
        mov ax,data
        mov ds,ax

        mov si,offset a
        mov cx,0000h

        back:   mov dl,byte ptr [si]
                cmp dl,'$'
        je skip
        inc cx
                inc si
        jmp back

    skip:   mov si,offset a
                mov bl,byte ptr[si]
                mov max,bl
        inc si
        abc:    mov bl,max
                cmp [si],bl
        jl ok
                mov bl,[si]
                mov max,bl
    ok: loop abc
        mov al,max
        int 03h
code ends
    end start

This is my programming assignment. I need to find out the largest among the array of integers using a method written in 8086 programming language. This is my attempt :

  #include <iostream.h>
    #include <conio.h>

    int returnLargest(int a[])
    {
        int max;
        asm mov si,offset a

        for(int i=0;i<6;i++) //Assuming six numbers in the array...Can be set to a variable 'n' later
        {
              asm mov ax,[si]
              asm mov max,ax
              asm inc si
              cout<<max<<"\n";    //Just to see what is there in the memory location
        }

        asm mov si,offset a
        asm mov cx,0000h

        asm  mov dx, [si]

            asm mov cx,06h

        skip: asm   mov si,offset a
        asm mov bx,[si]
        asm        mov max,bx
        asm inc si
        abc: asm   mov bx,max
           asm     cmp [si],bx
        asm jl ok
           asm     mov bx,[si]
              asm  mov max,bx
        ok: asm loop abc
        asm mov ax,max
        return max;
    }
    void main()
    {
        clrscr();
        int n;
        int a[]={1,2,3,4,5,6};
        n=returnLargest(a);
        cout<<n; //Prints the largest
        getch();
    }

The expected answer is

1
2
3
4
5
6
6. But what I get is this : enter image description here

Here I sit down and think... Is'nt it the value at the index i of array actually stored in the memory? Because atleast we were taught that if a[i] is 12(say) then ith memory location has the number 12 written inside it.

Or if the value is'nt stored at the memory location, How do I write into the memory location so as to accomplish the desired task?

Also I request you all to link some material on net/paperback so as to brush-up on these concepts.

EDIT :

The same code in assembly works just fine...

data segment
    a   db  01h,02h,03h,04h,05h,06h,'

    max db  ?
data ends

code segment
    start:
        assume cs:code,ds:data
        mov ax,data
        mov ds,ax

        mov si,offset a
        mov cx,0000h

        back:   mov dl,byte ptr [si]
                cmp dl,'

        je skip
        inc cx
                inc si
        jmp back

    skip:   mov si,offset a
                mov bl,byte ptr[si]
                mov max,bl
        inc si
        abc:    mov bl,max
                cmp [si],bl
        jl ok
                mov bl,[si]
                mov max,bl
    ok: loop abc
        mov al,max
        int 03h
code ends
    end start

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一念一轮回 2024-12-21 09:48:49

mov si,offset a 不正确。当函数参数声明为 int a[] 时,该函数实际上接收一个指针。由于您需要指针值 (a) 而不是其地址(C 中的 &a,汇编中的 offset a),请使用 mov si, a.

此外,inc si 似乎不正确 - 您需要为每个元素将 si 增加 sizeof(int)

编辑:

您正在将 C++ 代码(for 循环、cout)与程序集混合。 C++代码很可能使用相同的寄存器,这会导致冲突。你应该避免这样做。

您还需要找出您的函数可以根据所使用的调用约定更改哪些寄存器。如果您使用任何不允许更改的寄存器,则需要在开头push它们并在末尾pop它们。

mov si,offset a is incorrect. When you have a function parameter declared as int a[], the function actually receives a pointer. Since you want the pointer value (a) rather than its address (&a in C, offset a in assembly), use mov si, a.

Additionally, inc si doesn't seem right - you need to increase si by sizeof(int) for each element.

Edit:

You are mixing C++ code (for loop, cout) with your assembly. The C++ code is likely to use the same registers, which would cause conflicts. You should avoid doing this.

You also need to find out which registers your function is allowed to change according to the calling convention used. If you use any registers which aren't allowed to change, you need to push them at the beginning and pop them at the end.

奶气 2024-12-21 09:48:49

您必须确保您的编译器不使用您的寄存器。最好的方法是在汇编中编写整个函数并实现所需的调用约定(c-call 或 stdcall - 无论如何)。然后从 C/C++ 调用该函数。

然而,如果您知道您将只使用一个编译器以及它的工作原理,那么内联汇编器就不会有任何问题,但这确实是一个陷阱。

You will have to make sure your compiler doesnt use your registers. Best way would be to write the entire function in assembly and implement a desired calling convention (c-call or stdcall - whatever). Then call that function from C/C++.

However if you know you will use only one compiler and how it works you shouldnt have any problems by inlining assembler, but it's really a pitfall.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文