某公司招聘试题讨论 整理:病毒 (来源:绿色兵团)
--------------------------------------------------------------------------------
zzcat 于 2001-04-06 14:41:34 加贴在 编程乐园 上
--------------------------------------------------------------------------------
内容(1560bytes):
某公司招聘试题:
下面的汇编程序是用某个高级语言写成的函数经过编译后得到的目标文件。
1. 你估计这个函数是用哪种语言写的?原因?(提示:按调用方式区分)
2. 用这种语言写一个相同功能的函数。
proc1 proc near
push ebp
mov ebp, esp
sub esp, 18h
mov [ebp-4], 0
mov eax, [ebp+0CH]
mov [ebp-8], eax
mov [ebp-10H], 0
loc1:
mov eax, [ebp-10H]
cmp eax, [ebp+0CH]
jb short loc2
jmp short loc3
loc2:
mov eax, [ebp+8]
mov edx, [ebp-10H]
add eax, edx
xor edx, edx
mov dl, [eax]
mov [ebp-0CH], edx
mov eax, [ebp-0CH]
xor al, 0DAh
mov edx, [ebp-0CH]
xor edx, 0FFFFFFFFh
mov ecx, edx
xor cl, 0BFh
imul eax, ecx
mov edx, eax
imul edx, [ebp-0CH]
mov eax, edx
imul eax, [ebp-8]
add [ebp-4], eax
inc [ebp-8]
inc [ebp-10H]
jmp short loc1
loc3:
mov edx, [ebp-4]
mov eax, edx
mov esp, ebp
pop ebp
retn
proc1 endp
--------------------------------------------------------------------------------
病毒 于 2001-04-08 20:20:37 加贴在 编程乐园 上
--------------------------------------------------------------------------------
内容(64bytes):
有公司出这样的题目了,试想这样的代码在开发中,有何可读性而言?
zzcat 于 2001-04-09 08:58:41 加贴在 编程乐园 上
--------------------------------------------------------------------------------
内容(157bytes):
题是从别处转来的,不知道这是家什么公司,搞不定是专做盗版软件的
或者就是想考基本功,看人知不知道cdecl和pascal的区别.不过好像一般开
发没必要知道这个~~~~~~
病毒 于 2001-04-12 13:19:54 加贴在 编程乐园 上
--------------------------------------------------------------------------------
内容(68bytes):
在WIN32的编译器里不再需要PASCALL调用,大多数编译器已取消了对其的支持
--------------------------------------------------------------------------------
zzcat 于 2001-04-13 08:57:24 加贴在 编程乐园 上
--------------------------------------------------------------------------------
内容(58bytes):
WINAPI和stdcall用的还是PASCAL调用格式,子程序自己清理堆栈的
病毒 于 2001-04-13 13:05:13 加贴在 编程乐园 上
--------------------------------------------------------------------------------
内容(616bytes):
其实所谓的WINAPI就是__stdcall,这个在头文件里可以找到定义
列:#define WINAPI __stdcall 很明显这里沿用的是STDCALL格式
如果俺没记错的话,PASCAL调用是参数从左到右入栈,是调用者负责清理堆栈。
extern "C"是参数从右到左入,被调用者负责清理堆栈。 __stdcall是参数从
右到左,调用者负责清理堆栈而不是被调用者,还有就是所有的WIN32 SDK提供
的LIB都是以标准C形式存在的,且所有WIN32API都是以WINAPI即__stdcall调用
形式声明的,
列:
HWND
WINAPI
FindWindowA(
IN LPCSTR lpClassName,
IN LPCSTR lpWindowName);
WIN32编译器里真的以不在需要PASCALL调用,如VC6里已经取消了对PASCALL的支持,这点是肯定的。
realzjx 于 2001-04-13 22:16:34 加贴在 编程乐园 上
--------------------------------------------------------------------------------
内容(724bytes):
The __pascal, __fortran, and __syscall calling conventions are no longer supported.
c返回时候有时是ret 0004或者别的什么数清理堆栈。
而这个程序没有清理任务,
堆栈是自顶向下,mov eax, [ebp+0CH]又说明这个call一定是有参数的
而这里却直接ret返回
至于[ebp-10H][ebp-4]什么的一定是自动变量和寄存器变量。
自动变量虽然是char但堆栈也只能和必须为它开4个字节的空间。
程序大概是这样(指针也是32位的)
dword fun(char * data1,dword data2)
{long i,j; char k; long L;char m; char n;
i=0,j=data2;
L=0;
while(L++<data2)
{
k=*(data1+L);
m=k^0xda;
n=(~k)^0xbf;
i=m*n*k*j+i
j++;
}
return i;
}
我是用c的形式cause我不会pascal
我还是不知道这是什么语言编的,我用softice跟踪vc程序时,
很多子程序也不管清理堆栈,我很纳闷。
zzcat 于 2001-04-14 12:15:34 加贴在 编程乐园 上
--------------------------------------------------------------------------------
内容(356bytes):
入栈次序上cdecl跟stdcall已经统一了,但stdcall在返回值上是沿用pascal的办法,子程序返回时清理堆栈.cdecl则是标准c的办法,主程序自己清理堆栈.大家可以试一下,写这么一段程序:
cdecl int light(int x,int y)
{
return x+y;
}
_stdcall int dark(int x,int y)
{
return x+y;
}
调用可以看到,dark是ret 8;而light是ret,然后在主程序里add esp,8,所以开始那段程序用的是cdecl.
病毒 于 2001-04-14 13:34:46 加贴在 编程乐园 上
--------------------------------------------------------------------------------
内容(147bytes):
清栈工作是根据调用协议修饰符而定的,使用__cdecl后
在调用函数时,函数的参数将从右到左入栈,堆栈的清理工作
是由调用者来做,而不是被调用的函数来做。