从 C++ 访问汇编语言
这是我的编程作业。我需要使用 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 :
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
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 asint 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), usemov si, a
.Additionally,
inc si
doesn't seem right - you need to increasesi
bysizeof(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 andpop
them at the end.您必须确保您的编译器不使用您的寄存器。最好的方法是在汇编中编写整个函数并实现所需的调用约定(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.