【发布时间】:2015-06-30 21:16:38
【问题描述】:
我有一个外部函数和一个在token.c 中定义的struct:
#include "stdio.h"
typedef struct token {
int start;
int length;
} t;
extern t get_token(int, int);
t get_token(int s, int l) {
printf("[C] new token: start [%d] length [%d]\n\n", s, l);
t m_T = {};
m_T.start = s;
m_T.length = l;
return m_T;
}
... 这样我就可以从我的程序集中调用_get_token 并获得一个新令牌。在 make_token.asm 我有以下内容:
SECTION .data ; initialized data
mtkn: db "call: token(%d, %d)", 10, 0
mlen db "length: %d", 10, 0
mstt: db "start: %d", 10, 0
mend: db 10, "*** END ***", 10, 0
SECTION .text ; code
extern _get_token
extern _printf
global _main
_main:
; stash base stack pointer
push ebp
mov ebp, esp
mov eax, 5
mov ebx, 10
push ebx ; length
push eax ; start
call _get_token ; get a token
mov [tkn], eax
add esp, 8
; test token properties
push DWORD [tkn]
push mstt
call _printf
push DWORD [tkn + 4]
push mlen
call _printf
add esp, 16
.end:
push DWORD mend
call _printf
; restore base stack pointer
mov esp, ebp
pop ebp
SECTION .bss ; uninitialized data
tkn: resd 1
输出是:
[C] 新令牌:开始 [5] 长度 [10]
开始:5
长度:0
我缺少什么来获得开始和长度?输出验证 C 中的 extern 函数是否被调用,并且值被推送到函数中。
【问题讨论】:
-
如果我正确阅读了this table,那么您的答案的后半部分应该在 EDX 中 - “通过 EAX:EDX 寄存器返回大小为 33-64 位的 POD 返回值。”
-
1) 不要 typedef 结构定义。 2)由于该结构是在不同的文件中声明的,因此定义应该在头文件中,即两个源文件#include。 3) 引用外部函数不是通过 extern 完成的。而是在一个通用头文件中,该头文件包含在声明函数的源文件和通过#include 的本地文件中。头文件将具有原型,链接器处理其余部分。 4) #include 文件的搜索顺序取决于使用 '' 还是 '"..."'。系统标头应始终使用 ''
-
这一行:'return m_T;'将无法正常工作,因为当函数退出时,堆栈上的任何内容都会“丢失”,因此返回堆栈上的项目是未定义的行为。但是,由于返回的是实际的完整结构,而不是指针,因此编译器将调用 memcpy() 将结构复制到“隐藏”内存区域(不能用于其他任何内容),然后再次调用 memcpy() 以从隐藏的内存区域复制到调用者的变量。最好传递第三个参数,它是指向调用者的结构实例的指针,并使用该指针
-
请使用有意义的变量/参数名称。 's' 和 'l' 和 't' 很少或根本没有说明内容及其用法
-
假设发布的汇编代码是忠实的复制品,那么编译器只处理结构的第一个字段,即 I.E.它未能复制/返回第二个字段
标签: c windows call nasm extern