nasm,宏打印未按预期工作
nasm, macro print not working as expected
我正在从 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
根据标准调用约定,一些寄存器是调用者保存的,即eax
、ecx
和edx
。因此,您不应期望通过 call 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 文件调用一个用汇编语言编写的函数。 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
根据标准调用约定,一些寄存器是调用者保存的,即eax
、ecx
和edx
。因此,您不应期望通过 call 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