I was wondering,is there a difference in execution time between ++i and i++ in the for loop increment?
1)for(int i=0;i<100;++i)
2)for(int i=0;i<100;i++)
I have heard that the one with the pre-increment uses less registers, and hence, it is faster.
Is it correct?
Not these days no; if you can optimise it in your head then you can bet your bottom dollar that a compiler can also optimise it.
If you are in any doubt, check the generated assembly / bytecode &c.
This seems to be C code. In this case, there isn't any difference: try compiling those two sources with a compiler and ask it to keep intermediate assembler code.
Then use diff to see if the assembler files differ.
On FreeBSD with clang, on an x86_64 architecture, you can check that both of the files are strictly the same. The pre-increment is done the same way as the post-increment: addl $1, %eax.
Create x.c:
int main() {
for(int i=0;i<100;++i){}
}
Compile it:
% cc -S x.c
%
look at the code:
.file "x.c"
.text
.globl main
.align 16, 0x90
.type main,#function
main: # #main
.cfi_startproc
# BB#0:
pushq %rbp
.Ltmp2:
.cfi_def_cfa_offset 16
.Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
.Ltmp4:
.cfi_def_cfa_register %rbp
movl $0, -4(%rbp)
movl $0, -8(%rbp)
.LBB0_1: # =>This Inner Loop Header: Depth=1
cmpl $100, -8(%rbp)
jge .LBB0_4
# BB#2: # in Loop: Header=BB0_1 Depth=1
jmp .LBB0_3
.LBB0_3: # in Loop: Header=BB0_1 Depth=1
movl -8(%rbp), %eax
addl $1, %eax
movl %eax, -8(%rbp)
jmp .LBB0_1
.LBB0_4:
movl -4(%rbp), %eax
popq %rbp
ret
.Ltmp5:
.size main, .Ltmp5-main
.cfi_endproc
.ident "FreeBSD clang version 3.4.1 (tags/RELEASE_34/dot1-final 208032) 20140512"
.section ".note.GNU-stack","",#progbits
Do the same with --i instead of ++i.
Related
I'm new to Y86 and am trying to write a recursive multiplication function, but the wrong parameter keeps being passed.
The code that calls the multiplication function:
square:
irmovl $4, %ebx
pushl %ebx # push argument
rrmovl %ebx, %edx #set it equal to the number being squared
pushl %edx
call rmult
popl %edx
popl %ebx
ret
And the actual multiplication code:
rmult:
pushl %ebp
rrmovl %esp,%ebp
mrmovl 8(%ebp),%ebx #ebx = y
irmovl $0,%eax
rrmovl %ebx,%edi
subl %ebx,%eax
je rec_multend
rrmovl %ebx,%esi
irmovl $1,%eax
subl %eax,%esi
pushl %ebx
pushl %esi
call rmult
mrmovl 12(%ebp),%edx #edx = x
popl %esi
popl %ebx
addl %edx,%edi
rec_multend:
popl %ebp
ret
I pass in 4 for both x and y as the function calling them is squaring a number and so they should be the same, but at the line:
mrmovl 12(%ebp),%edx #edx = x
It passes in 2 instead of the 4 that I initially put in there, which ends up returning a value of 13 rather than 16.
From my limited understanding of Y86, "mrmovl 8(%ebp),%ebx" should return the second parameter which I set equal to Y and "mrmovl 12(%ebp),%edx" should return the first parameter equal to X, with both of them being passed in as 4.
I'm trying to optimize the calculation of a dot product by using the registers and instructions included in the MMX and SSE extentions.
When I insert the line seen below, though, gcc is giving me an error about bad register names for %xxmX registers
.L3:
movl -8(%ebp), %eax
leal 0(,%eax,4), %edx
movl 8(%ebp), %eax
addl %edx, %eax
movups (%eax), %xxm0 <--------------------
flds (%eax)
movl -8(%ebp), %eax
leal 0(,%eax,4), %edx
movl 12(%ebp), %eax
addl %edx, %eax
flds (%eax)
fmulp %st, %st(1)
flds -4(%ebp)
faddp %st, %st(1)
fstps -4(%ebp)
addl $1, -8(%ebp)
when compiled with
gcc -m32 -march=corei7 dot_product.s
I get
dot_product.s: Assembler messages:
dot_product.s:24: Error: bad register name `%xxm0'
I have the corei7 architecture as show below
dpkg --print-foreign-architectures
yields
i386
corei7
any idea why gcc is throwing an error?
I've been trying to learn how to create an IRC bot in assembler from some old sources. Everything is going fine with my learning except for a prefix problem.
The prefix for the bot is:
CommandPrefix equ "^^"
And the length of the prefix is added with:
add eax, 2d
I want to change the prefix to just "^", but I am having trouble with figuring out what "add eax" should be changed too for it to work. Or even if that is the best way to do it. Any help with this would be appreciated.
Here is what the original code looks like to get some idea:
include "win32ax.inc"
entry Bot
CommandPrefix equ "^^"
section '.code' code readable executable
Bot:
invoke WSAStartup,0101h,WSAData
cmp eax, 0
jne Exit
invoke socket,AF_INET,SOCK_STREAM,0
cmp eax, -1
je Exit
mov dword [SocketDesc], eax
invoke inet_addr,IRCServer
mov dword [SockAddr_IP], eax
invoke htons,IRCPort
mov word [SockAddr_Port], ax
invoke connect,dword [SocketDesc],SockAddr,16d
cmp eax, 0
jne Exit
call GenerateNickname
invoke lstrcpy,SendBuffer,"NICK "
invoke lstrcat,SendBuffer,Nickname
call SendLine
invoke lstrcpy,SendBuffer,"USER "
invoke lstrcat,SendBuffer,Nickname
invoke lstrcat,SendBuffer," 8 * :"
invoke lstrcat,SendBuffer,Nickname
call SendLine
GetMotd:
call RecvLine
call HandlePing
mov ecx, 0
IsMotd:
cmp dword [ReturnBuffer + ecx], "MOTD"
je HaveMotd
cmp byte [ReturnBuffer + ecx], 0d
je GetMotd
inc ecx
jmp IsMotd
HaveMotd:
invoke lstrcpy,SendBuffer,"JOIN "
invoke lstrcat,SendBuffer,Channel
invoke lstrcat,SendBuffer," "
call SendLine
RecvCommand:
call RecvLine
call HandlePing
mov ecx, 0
IsCommand:
cmp word [ReturnBuffer + ecx], CommandPrefix
je HaveCommand
cmp byte [ReturnBuffer + ecx], 0
je RecvCommand
inc ecx
jmp IsCommand
HaveCommand:
mov ebx, ReturnBuffer
add ebx, ecx
add ebx, 2d ;add length of command prefix
invoke lstrcpy,CommandBuffer,ebx
call ExecuteCommand
jmp RecvCommand
This file is in AT&T syntax - see http://www.imada.sdu.dk/Courses/DM18/Litteratur/IntelnATT.htm
and http://en.wikipedia.org/wiki/X86_assembly_language#Syntax. Both gdb and objdump produce
AT&T syntax by default.
MOV $27163,%ebx
MOV $13156,%eax
MOV $25880,%ecx
CMP %eax,%ebx
JL L1
JMP L2
L1:
IMUL %eax,%ebx
ADD %eax,%ebx
MOV %ebx,%eax
SUB %ecx,%eax
JMP L3
L2:
IMUL %eax,%ebx
SUB %eax,%ebx
MOV %ebx,%eax
ADD %ecx,%eax
L3:
NOP
What is the value of %eax when the last instruction NOP runs?
The answer is "%933%". (no quotes)
I get an EXC_BAD_ACCESS error in the iPhone Simulator when I try to change the pointer to the current malloc function pointer with my own implementation:
malloc_zone_t *zone = malloc_default_zone();
zone->malloc = my_malloc;
Assembly:
0x2b73: movl $0, %ecx
0x2b78: leal -40(%ebp), %edx
0x2b7b: movl -92(%ebp), %esi
0x2b7e: movl 13828(%esi), %edi
0x2b84: movl %eax, -76(%ebp)
0x2b87: movl -76(%ebp), %eax
0x2b8a: movl %edi, 12(%eax) <------ EXC_BAD_ACCESS (code=2, address=0x675100c
0x2b8d: movl 16836(%esi), %eax
0x2b93: movl 16588(%esi), %edi
0x2b99: movl %eax, (%esp)
0x2b9c: movl %edi, 4(%esp)
0x2ba0: movl %ecx, -132(%ebp)
0x2ba6: movl %edx, -136(%ebp)
I also get an error even if I try to change a simple field like version:
zone->version = 9;
Old but here's an answer.
The default zone is write protected, for a workaround, see:
http://trac.webkit.org/changeset/53362/trunk/WebKitTools/DumpRenderTree/mac
As I know malloc_default_zone() used by in OS X only. You can check this fact in help.
So this function may not works right on iPhone.