1
YUCOAT OP 编译器是Gcc 4.6x,不知道Windows下的vs编译器的结果是什么。
我阅读了一下stdarg.h的源码,想看看va_list/va_start的实现,但是被那些宏给绕晕了 |
2
SErHo 2013-09-11 22:47:41 +08:00 1
在Windows下使用gcc就是正常的,32位。
|
3
SErHo 2013-09-11 22:50:24 +08:00
Windows VS2012 也正常。
|
4
timonwong 2013-09-11 22:54:04 +08:00 1
x86_64头几个是使用的通用寄存器,其它的才是栈上的。
http://en.wikipedia.org/wiki/X86_calling_conventions |
6
VYSE 2013-09-12 01:57:40 +08:00
楼主你是不是用了64位编译?内存地址都超了,64下就得用__int64一个个遍历了
|
8
onemoo 2013-09-12 08:46:55 +08:00
LZ试试不用这段“int* int_ptr = &count;”来取地址。
而是用汇编从%ebp开始向高址位去找找。 或者直接将你的这段代码汇编输出,看看int_ptr是不是指向调用帧的压栈区。 还有,不要用任何优化... |
9
jiumingmao 2013-09-12 09:08:32 +08:00
用 va_start va_arg va_end 试试
|
10
LetFoxRun 2013-09-12 09:17:15 +08:00
@jiumingmao +1
|
11
pezy 2013-09-12 09:30:12 +08:00
完全取决于你用多少位的编译器。在Windows下用TDM-GCC 4.7.1 32位编译器,按照楼主的代码,就可以得到想要的答案。如果用64位,则需要将++int_ptr改为int_ptr += 2了,也是可以得到楼主想要的结果的。
我觉得这至少能证明楼主你的思路是对的。 当然比较成熟的方案还是使用va_start va_arg va_end了。 |
12
Jex 2013-09-12 11:52:33 +08:00 1
其实GCC在处理函数调用时,参数并不总是用栈传递的。
之前我回答过一个类似的问题:http://zhi.hu/VQVA 这里有不同的函数参数传递形式的列表:http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 楼上有说什么fastcall与cdecl。楼主代码显然是在64位平台上编译的。 通过`gcc -S` 命令输出汇编代码,就会看到实际上参数是通过寄存器传递的 ``` main: .LFB1: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 movq %rsp, %rbp .cfi_offset 6, -16 .cfi_def_cfa_register 6 movl $50, %r8d movl $40, %ecx movl $30, %edx movl $20, %esi movl $4, %edi movl $0, %eax call arg movl $0, %eax leave ``` |
13
johnnyb 2013-09-15 00:44:07 +08:00
看了一下汇编,确如楼上所说,是通过寄存传递的。va_start/va_end/va_arg 的实现也被"隐藏"起来了:
#define va_start(ap, param) __builtin_va_start(ap, param) #define va_end(ap) __builtin_va_end(ap) #define va_arg(ap, type) __builtin_va_arg(ap, type) 这几个 __builtin 是怎么实现的? |