gpt4 book ai didi

c - nasm,宏打印未按预期工作

转载 作者:行者123 更新时间:2023-11-30 17:13:58 24 4
gpt4 key购买 nike

我正在从 C 文件调用用汇编语言编写的函数。 C 代码将两个指针传递给汇编函数。我在程序集中使用打印宏来检查地址及其指向的元素的值。

这是 C 代码:

extern int nn_from_set(float *q, float *t, int q_length, int *s, int s_length);

int main()
{
float *matrix_dyn = malloc(6*4*sizeof(float));
int *s = malloc( 3 * sizeof(int))
//the vectors are filled here
//print their address, no problem here
printf("t: %p, s: %p, sizeof int*: %u\n", matrix_dyn, s, sizeof(matrix_dyn));
//assembly function called
printf("Prova: %d\n", nn_from_set(matrix_dyn, matrix_dyn, 3, s, 3));
return 0;
}

这是汇编代码,有点长。

extern printf

%macro pabc 1 ; a "simple" print macro
section .data
.strm db %1,0 ; %1 is first actual macro call

section .text

; push onto stack bacwards
push dword [nnfs_int] ; int a
push dword .strm
push dword nnfs_fmt_int ; users string
call printf ; call C function
add esp, 12 ; pop stack 3 * 4 bytes

%endmacro

section .data
fmt: db "%s, dist: %e",10,0 ; format string for printf
nnfs_fmt: db "%s",10,0 ; format string for printf
nnfs_fmt_int: db "%s %p",10,0 ; format string for int debug


section .bss

nnfs_dst: resd 1 ; reserve 32-bit word
nnfs_tmp: resd 1 ; int tmp;
nnfs_index: resd 1 ; reserve 32-bit, int index;
nnfs_int: resd 1

section .text

; function to be translated is
; int nearest_neighbor_from_set(float* q, float* t, int q_length, int* s, int s_length)

global nn_from_set

nnfs_q equ 8
nnfs_t equ 12
nnfs_q_length equ 16
nnfs_s equ 20
nnfs_s_length equ 24

nn_from_set:
; -------------------------------------------
; Entrace sequence
; -------------------------------------------
push ebp ; save base pointer
mov ebp, esp ; point to current stack frame
push ebx ; save general registers
push esi
push edi

mov ecx, [ebp + nnfs_t] ; t
mov edx, [ebp + nnfs_s] ; s

mov [nnfs_int], ecx ; print t
pabc "ecx, t: "

mov [nnfs_int], edx ; print s
;pabc "edx, s: "

mov esi, [edx] ; *s

mov [nnfs_int], esi ; print *s
;pabc "edx"

add edx, 4
mov esi, [edx]

mov [nnfs_int], esi
;pabc "esi"

; fine di nn_from_set
mov eax, 50 ; for test purpose

; ------------------------------------------
; Exit sequence
; ------------------------------------------

pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret

我有两个问题,使用这个版本的代码,当我尝试编译时,它说 .strm 已经定义,每次我在第一次调用后尝试调用宏时都会如此。

第二个问题。我这样更改宏:

 %macro pabc 1           ; a "simple" print macro

section .text

; push onto stack bacwards
push dword [nnfs_int] ; int a
push dword nnfs_fmt_int ; users string
call printf ; call C function
add esp, 8 ; pop stack 2 * 4 bytes

%endmacro

我删除了 .strm 参数。现在的格式字符串是:

nnfs_fmt_int:   db " reg %p",10,0

在这个版本中,宏的第一次调用打印正确,第二次调用出错。例如我调用宏打印两个指针的地址:

mov [nnfs_int], ecx         ; print t
pabc "ecx, t: "

mov [nnfs_int], edx ; print s
pabc "edx, s: "

这是输出(第一行是从 C 文件打印的):

t: 0x8500008, s: 0x8500070, sizeof int*: 4
reg 0x8500008
reg 0xf7778898

t 的地址打印正确,s 的地址打印错误。如果我反转这两个调用。

mov [nnfs_int], edx         ; print s
pabc "ecx, t: "

mov [nnfs_int], ecx ; print t
pabc "edx, s: "

这是输出(第一行是从 C 文件打印的):

t: 0x93a0008, s: 0x93a0070, sizeof int*: 4
reg 0x93a0070
reg (nil)

S 打印正确,但 t 打印错误。

我不知道出了什么问题,我使用了相同的宏模式,到目前为止还没有给我带来任何问题。我用来创建此宏的示例来自此处:http://www.csee.umbc.edu/portal/help/nasm/sample.shtml

最佳答案

根据标准调用约定,一些寄存器是调用者保存的,即eaxecxedx。因此,您不应期望通过调用 printf 保留它们的值。这可能就是您打印错误值的原因。您可以在打印第一个之前将第二个放入堆栈中,然后将其弹出以打印第一个。实际上,由于这些已经在堆栈中,您可以从那里重新加载:

mov ecx, [ebp + nnfs_t]     ; t
mov [nnfs_int], ecx ; print t
pabc "ecx, t: "

mov edx, [ebp + nnfs_s] ; s
mov [nnfs_int], edx ; print s
pabc "edx, s: "

; reload since printing changed ecx and edx
mov ecx, [ebp + nnfs_t] ; t
mov edx, [ebp + nnfs_s] ; s

关于c - nasm,宏打印未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30531358/

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