gpt4 book ai didi

c - 8086/386 asm 与 bcc5 : returning long int from asm proc

转载 作者:行者123 更新时间:2023-11-30 14:22:14 35 4
gpt4 key购买 nike

尝试通过 eax 从 asm proc 返回一个 long int,后来又尝试通过 dx:ax。两者都不适合我,因为 C printf 打印的数字与所需的 320L 不同。

x.asm:

.model SMALL
.stack 100h
.code
.386
; extern int get_buffered_long(long int **arr, int num_of_elements, int i);
; [BP+4] [BP+6] [BP+8]
PUBLIC _get_bufferred_long
_get_bufferred_long PROC NEAR
push BP
mov BP,SP
push SI
push DI
push BX
call locate_slot
;mov EAX, DWORD PTR [DI] ;something here doesn't work. the way i return a long int to borland C, or other issue.
mov ax,[DI]
mov dx,[DI+2]
pop BX
pop DI
pop SI
pop BP
ret
_get_bufferred_long ENDP
; extern void set_bufferred_long(long int *arr[], int buff_size, int i,long int value);
; [BP+4] [BP+6] [BP+8] [BP+10]
PUBLIC _set_bufferred_long
_set_bufferred_long PROC NEAR
push BP
mov BP,SP
pushad
call locate_slot
mov EAX,[BP+10]
mov DWORD PTR [DI],EAX
popad
pop BP
ret
_set_bufferred_long ENDP
; helper function that makes DI point to the slot wanted.
locate_slot PROC NEAR
calc_slot:
mov SI,[BP+4]
mov AX,[BP+8]
mov BX,[BP+6]
xor DX,DX
div BX
locate_slot_in_array:
shl AX,1
add SI,AX
mov DI,[SI]
shl DX,2
add DI,DX
ret
locate_slot ENDP
end

y.c:

#include "stdio.h"
#include "stdlib.h"

extern int get_bufferred_long(long int**,int,int);
extern void set_bufferred_long(long int**,int,int,long int);

int main(){
long int **arr;
int i,j,n,m;
n = 5;
m = 4;
arr=(long int**)malloc(n*sizeof(long int*));
for(i=0; i < n; i = i + 2) arr[i] = malloc( m*sizeof(long int));
for(i=1; i < n; i = i + 2) arr[i] = malloc( m*sizeof(long int));
for(i=0; i < n; i++)
for(j=0; j < m; j++)
set_bufferred_long(arr, m, i*m+j, i*100+j*10);

printf("get_bufferred_long(arr, %d, %d) = %ld\n", m, 14, get_bufferred_long(arr,m, 14));
return 0;
}

set 函数有效(数组看起来与需要的完全一样)。 get函数也可以工作,它在asm中获取320L,但是当传递给C时,出现了问题。

没有编译错误或警告。borland c++ 5.02

最佳答案

嗯,在 386 bcc 上确实在 16 位模式下使用 AX:DX;不知道32位。

但是看看你的代码!

    ...
mov dx,[DI+2]
mov ax,[DI]
mov dx,[DI+2]
pop DX
...

您正在将结果加载到 DX 寄存器,然后将堆栈弹出到其中,从而清除它所具有的值。 DX 不必通过简单过程中的推送/弹出来保存(仅在 DOS ISR 中)。

编辑

好的,我看到您在代码中解决了上述问题。下一个问题可能是您声明

/* After execution, return value is assumed to be in AX. */ 
extern int get_bufferred_long(long int**,int,int);

然后期望一个 32 位返回值。您提到 printf 正在推送 AX 寄存器。这意味着您正在编译为 16 位代码。如果您想要 16 位代码中的 32 位返回值,则必须声明返回值 long 并将其放置在 DX:AX 中。

/* After execution, return value is assumed to be in DX:AX reg pair. */
extern long get_bufferred_long(long int**,int,int);

您可以通过使用 -S 选项将一个小程序编译为程序集来验证正确的返回约定。尝试例如:

long val(void) { return 0x12345678L; }

查看生成的程序集,看看编译器如何返回这个长值。

关于c - 8086/386 asm 与 bcc5 : returning long int from asm proc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13925605/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com