0

I wrote a statement in visual studio.

int sum(int a, int b){
    return a + b;
}  
int main(){
    tong(3,4);
    return 0;
}

And aften i use ida pro Disassembly it. And my function tong has registers, such as: esi, edi, that i think them willn't be used, i think it use only registers: eax, ebp, esp. Why does ida use them?

.text:004113C0 ; int __cdecl tong(int a, int b)
.text:004113C0 ?tong@@YAHHH@Z  proc near               ; CODE XREF:     tong(int,int)j
.text:004113C0
.text:004113C0 var_C0          = byte ptr -0C0h
.text:004113C0 a               = dword ptr  8
.text:004113C0 b               = dword ptr  0Ch
.text:004113C0
.text:004113C0                 push    ebp
.text:004113C1                 mov     ebp, esp
.text:004113C3                 sub     esp, 0C0h
.text:004113C9                 push    ebx
.text:004113CA                 push    esi
.text:004113CB                 push    edi
.text:004113CC                 lea     edi, [ebp+var_C0]
.text:004113D2                 mov     ecx, 30h
.text:004113D7                 mov     eax, 0CCCCCCCCh
.text:004113DC                 rep stosd
.text:004113DE                 mov     eax, [ebp+a]
.text:004113E1                 add     eax, [ebp+b]
.text:004113E4                 pop     edi
.text:004113E5                 pop     esi
.text:004113E6                 pop     ebx
.text:004113E7                 mov     esp, ebp
.text:004113E9                 pop     ebp
.text:004113EA                 retn
.text:004113EA ?tong@@YAHHH@Z  endp

Can anyone explain their meaning?

UPDATE 1

.text:00411400 ; int __cdecl main()
.text:00411400 _main           proc near               ; CODE XREF: j__mainj
.text:00411400
.text:00411400 var_C0          = byte ptr -0C0h
.text:00411400
.text:00411400                 push    ebp
.text:00411401                 mov     ebp, esp
.text:00411403                 sub     esp, 0C0h
.text:00411409                 push    ebx
.text:0041140A                 push    esi
.text:0041140B                 push    edi
.text:0041140C                 lea     edi, [ebp+var_C0]
.text:00411412                 mov     ecx, 30h
.text:00411417                 mov     eax, 0CCCCCCCCh
.text:0041141C                 rep stosd
.text:0041141E                 push    4               ; b
.text:00411420                 push    3               ; a
.text:00411422                 call    j_?tong@@YAHHH@Z ; tong(int,int)
.text:00411427                 add     esp, 8
.text:0041142A                 xor     eax, eax
.text:0041142C                 pop     edi
.text:0041142D                 pop     esi
.text:0041142E                 pop     ebx
.text:0041142F                 add     esp, 0C0h
.text:00411435                 cmp     ebp, esp
.text:00411437                 call    j___RTC_CheckEsp
.text:0041143C                 mov     esp, ebp
.text:0041143E                 pop     ebp
.text:0041143F                 retn
.text:0041143F _main           endp
  • I don't see tong function definition in the C code. Should it be so ? Which optimization level did you set for compiler ? – w s Oct 20 '16 at 12:52
  • I use default ida. And i run good code C ??? – QChí Nguyễn Oct 20 '16 at 13:14
  • Your assembly code contains only one function named "tong". TThe definition of this function is missing in the C code (there is only call to it). It is hard to answer your question without the code you are asking about. – w s Oct 20 '16 at 13:22
  • OK i updated it – QChí Nguyễn Oct 20 '16 at 13:33
1

Seems like you renamed the tong function to sum in your C code, but not in assembly, which is from where some of the confusion comes.

Why does IDA use those registers? Well, because that's the assembly that the compiler produced from your C code. IDA just uses what's there. So the better question would be:

Why did the compiler produce code that uses ebx, esi, edi, ecx, ... when only eax would need to be used?

Actually, the only lines from your tong function that are really neccesary are

.text:004113C0                 push    ebp
.text:004113C1                 mov     ebp, esp
.text:004113DE                 mov     eax, [ebp+a]
.text:004113E1                 add     eax, [ebp+b]
.text:004113E9                 pop     ebp
.text:004113EA                 retn

(and in theory you don't even need to use ebp; you could just use esp do index the stack, saving you another two lines).

The rest is due to compiler flags - optimization level and stack checking level. These lines seem to check if the stack gets smashed somewhere:

.text:00411403                 sub     esp, 0C0h
.text:0041140C                 lea     edi, [ebp+var_C0]
.text:00411412                 mov     ecx, 30h
.text:00411417                 mov     eax, 0CCCCCCCCh
.text:0041141C                 rep stosd
.....
text:00411437                 call    j___RTC_CheckEsp

which allocates 192 (hex C0) bytes on the stack, fills them with CC, and later calls a function that supposedly checks if those CC bytes are still there. This smashes eax, ecx and edi. If you disable stack checking somewhere in the compiler options, this part will be omitted.

Also, the compiler probably has a convention that functions should never change ebx, esi and edi. Which is why it produces push operations at the start, and pop and the end, for these registers, of the function. If optimization was turned higher, it would probably note that esi and ebx are never used in the function, so it'd optimize those lines out.

So to sum it up: in addition to your C code, the compiler does some internal housekeeping, which produces code that accesses more registers than your code alone would need. Messing with compiler options changes the amount of housekeeping that's needed. And IDA just displays what's there, it doesn't have a say in what the assembly, produced by the compiler, contains or doesn't contain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.