Jump to content


Check out our Community Blogs

dargueta

Member Since 07 Oct 2007
Offline Last Active May 18 2019 05:29 PM
*****

#639355 Programming homework help

Posted by dargueta on 20 September 2012 - 07:29 PM

Yes, but you have to be careful. The first 1 you encounter is not likely to be the right bit. Look at the example number - if you return the position of the first bit set to 1, you're gonna be wrong. You can do it one of two ways

1) Start at the highest bit and shift right until you hit the first 1, then return that.
2) Start at the lowest bit and shift left until you hit the last 1, then return that.

Make sure you handle the case where n = 0.
  • 1


#638701 Please Provide a Source Code for this Problem...

Posted by dargueta on 13 September 2012 - 12:33 PM

Mod note: Moved to homework forum.

Do you have to use Lex and/or Bison for this? What language?
  • 0


#638555 [SOLVED] C - Sum a 2d array each column and each row separately

Posted by dargueta on 12 September 2012 - 12:23 PM

Still, its an unofficial policy to help but not do. I'll see if I can amend the rules to make it official.

This topic has been marked as SOLVED. If you have a similar question or topic, you can go back to the subforum and start a new topic to continue discussions.
  • 1


#638496 [PHP] Store session

Posted by dargueta on 12 September 2012 - 01:19 AM

So I'm getting the impression that you want to fill all the applicable fields from Personal Detail into Academic Detail when the Academic Detail page is loaded? In that case you're either going to have to store session data (probably cookies) or use some database and dynamically generate the contents of Academic Detail.
  • 1


#638185 [C++] Trimming char* argv[]

Posted by dargueta on 09 September 2012 - 12:37 PM

#include <ctype.h>

char mystring[] = "a string with spaces";
char *cur, *next;

/* If you want to copy the string, just set cur to a new char buffer. */
cur = next = mystring;

do
{
	if( !isspace(*next) )
		*cur++ = *next;
} while( *next++ != '\0' );

No need to use strlen on every iteration, which would slow you down considerably, and also saves memory by replacing the string in-place. Easily modifiable to copy the string instead of overwriting it.

Also - never overwrite anything in argv; always make a copy first. This is undefined behavior and can cause segmentation faults and other bad things on some systems.
  • 1


#636163 [SOLVED] Assembly Code Breakdown && Help

Posted by dargueta on 15 August 2012 - 07:10 PM

AT&T syntax is a lot uglier and mangles mnemonics (which for some reason wasn't done here). Registers must be prefixed with %, integer constants must have $ in front of them, etc.

All functions eventually return control to whatever called them in some form or another. The simplest form is this:

push    ebp
mov     ebp, esp

... function code in here...

pop     ebp
ret

As for tutorials and stuff, look at the pinned thread at the top of the assembly forum titled Assembly Language Resources. You'll find just about everything you need there, not just for Intel, but also MIPS, SPARC, ARM, and a few other languages.
  • 1


#636102 [SOLVED] Assembly Code Breakdown && Help

Posted by dargueta on 15 August 2012 - 11:01 AM

Just for your information, I'm translating your code to Intel syntax instead of AT&T because it's easier to read and I'm less likely to mess up. Warning: AT&T operands are backwards; with Intel syntax mov x, y means x = y, not y = x as in AT&T syntax. Anyway:


0x8048430 <triangle>:    push   ebp
0x8048431 <triangle+1>:  mov    ebp, esp
0x8048433 <triangle+3>:  push   edi
0x8048434 <triangle+4>:  push   esi
0x8048435 <triangle+5>:  sub    esp, 0x30
0x8048438 <triangle+8>:  lea    edi, [ebp + 0xffffffd8]
0x804843b <triangle+11>: mov    esi, 0x8049508
0x8048440 <triangle+16>: cld
0x8048441 <triangle+17>: mov    esp, 0x30
0x8048446 <triangle+22>: repz   movsw
0x8048448 <triangle+24>: mov    eax, [ebp + 0x08]
0x804844b <triangle+27>: mov    edx, eax
0x804844d <triangle+29>: imul   edx, [ebp + 0x0c]
0x8048451 <triangle+33>: mov    eax, edx
0x8048453 <triangle+35>: sar    eax, 0x1f
0x8048456 <triangle+38>: shr    eax, 0x1f
0x8048459 <triangle+41>: lea    eax, [eax + edx]
0x804845c <triangle+44>: sar    eax
0x804845e <triangle+46>: mov    [ebp + 0xffffffd4], eax
0x8048461 <triangle+49>: mov    eax, [ebp + 0xffffffd4]
0x8048464 <triangle+52>: mov    eax, eax
0x8048466 <triangle+54>: add    esp, 0x30
0x8048469 <triangle+57>: pop    esi
0x804846a <triangle+58>: pop    edi
0x804846b <triangle+59>: pop    ebp
0x804846c <triangle+60>: ret
Doesn't that make a bit more sense?

Now for the explanation:
push    ebp
mov     ebp, esp

This saves the base pointer (EBP) and sets it to point to the top of the stack. EBP is traditionally used to access arguments. For example, EBP + 4 is the first argument, EBP + 8 is the second, etc. Notice that +4 is the first argument, because the return address is at EBP + 0. Do not forget that, you might overwrite your return address and regret it later.

push    edi
push    esi
Here we're just saving the EDI and ESI registers. GCC specifies that functions must preserve the values of certain registers while executing. The callee is free to use them, but it must restore them to whatever the caller had before. These are like the s0-s7 registers in MIPS.

sub     esp, 0x30
Reserves 0x30 bytes of space for local variables on the stack. ESP is used to index local variables, EBP for arguments.

lea     edi, [ebp + 0xffffffd8]

The lea instruction is often used to perform more complex arithmetic operations. For example, lea eax, [ecx + edx*8] is equal to:

mov     eax, edx
shl     eax, 3
add     eax, ecx
Anyway, this adds 0xffffffd8 to EBP and stores the value in EDI. Don't ask me why, I have no idea.

mov     esi, 0x8049508
This looks like ESI is being set to a pointer to a global variable at memory location 0x8049508. Considering they're using movsw later, I'd bet that this is the {1, 2, 3, 4, 5} array.

cld
mov     esp, 0x30
repz    movsw
Clears the direction flag, which is used by movsw to determine whether it should go forwards (DF=0) or backwards (DF=1). I have no idea why they're setting ESP to 0x30; if anything, it should be ECX. The movsw instruction copies words (two bytes) from DS:[ESI] to ES:[EDI] and increments each pointer. The repz prefix says "Do the next instruction, decrement ECX. Keep executing the instruction until ECX is zero."

mov     eax, [ebp + 0x08]
mov     edx, eax
This sets EAX to the first argument and copies that value to EDX, so now EDX = EAX = width.

imul    edx, [ebp + 0x0c]
mov     edx, eax
Multiply EDX by the value of the second argument (height) and copy the result to EAX. Now EDX = EAX = width*height.

sar     eax, 0x1f
shr     eax, 0x1f
This divides EAX by 2^31, filling the upper bits with the original upper bit, so the result may not necessarily be zero. The least-significant bit is now the original sign bit (the uppermost one). SAR stands for shift arithmetic right.

After that, EAX is divided once again by 2^31, but this time filling the upper bits with zeroes (shift logical right). EAX should be equal to the original sign bit. I have no idea why they do this, because this can just as easily be done with shr eax, 0x1f.

lea     eax, [eax + edx]
Adds the sign bit to EDX and stores the result in EAX. This could be adding 1 or 0, depending on the result of the multiplication. Um...

sar     eax
This isn't even valid - it's missing an operand. Did you copy this by hand?


mov    [ebp + 0xffffffd4], eax
mov    eax, [ebp + 0xffffffd4]
Sets the 32-bit integer at [ebp + 0xffffffd4] to EAX, then sets EAX back to that value we just wrote. What?!

mov     eax, eax
This does nothing.

add     esp, 0x30
pop     esi
pop     edi
pop     ebp
ret
Undoes all of the changes made at the beginning of the function; it cleans up the space allocated for the local variables, restores ESI, EDI, and EBP, then returns.

All in all, this code shouldn't work.
  • 1


#635535 [SOLVED] Dynamic Linking to C library on linux

Posted by dargueta on 08 August 2012 - 10:12 AM

Change pushq $string to movq $string, %rdi. That might work, if the problem is what I think it is.

Check out the first answer here.
  • 1


#634002 [SOLVED] Question In Tracing In C++

Posted by dargueta on 16 July 2012 - 12:14 AM

This topic has been marked as SOLVED. If you have a similar question or topic, go back to the subforum and start a new topic to continue discussions.
  • 1


#633888 [SOLVED] Question In Tracing In C++

Posted by dargueta on 14 July 2012 - 12:15 PM

That's because there's no break statement after case 1, so it keeps executing until it hits the first break in case 5. This is called "falling through" and is a very common mistake for beginning programmers. Put a break after case 1 and you'll get 2 as your output.

switch( x )
{
    case 1:
        x = x + 1;
        break;

    case 3:
        x = x + 2;
        break;

    case 5:
        x = x + 6;
        break;

    case 6:
        x = x + 3;
        break;

    default:
        x = x - 1;
        break;
}

Now it'll behave as expected.
  • 1


#633749 A More Efficient Search

Posted by dargueta on 12 July 2012 - 01:09 PM

If that's the case then I recommend you use a map, and iterate through your gazillion MAC strings, blindly pulling out the MAC addresses and their strengths, then putting them into the map. Once you're done you can check directly in the map and find those strengths in log(n) time instead of doing a bunch of checks while going in the loop.

For example, if you're searching for 100 MAC addresses in 20,000 records, with your current method the worst-case scenario is 2,000,000 comparisons for insertion alone. If you use a map, the total comparisons including insertion and lookup is at worst 140,007.
  • 1


#633515 A More Efficient Search

Posted by dargueta on 09 July 2012 - 11:41 PM

Nonononono. Never hard-code things like that, it'll get incredibly messy and if you ever need to add or remove a MAC address it'll get ugly. Use the loop like I suggested above. If you ever have to do something repeatedly on different inputs, put it in a loop; if the loop gets too big, break it up into a few functions and call them in a smaller loop.
  • 1


#633512 A More Efficient Search

Posted by dargueta on 09 July 2012 - 11:19 PM

Don't do any more computation than you have to; only search for the second MAC address if you haven't found the first:
size_t index;

index = array[i].find("00:24:6c:86:17:c2");

if( index != std::string::npos )
{
    bir[a] = array[i].substr(index + 18, 6);
    ++a;
}
else
{
    index = array[i].find("50:67:f0:e7:d9:1c");
    if( index != std::string::npos )
    {
        iki[b] = array[i].substr(index + 18, 6);
        ++b;
    }
    // If you want to handle a case where neither is found, put that code in
    // an else block here.
}

Trust me, in a loop with worst-case 40000 searches to do, you want to do as few as necessary.
  • 1


#631543 Arithmetic With Roman Numerals In Mips

Posted by dargueta on 11 June 2012 - 12:42 PM

Start here, write it in C. From there converting it to MIPS shouldn't be too hard.
http://computeralgor...s-to-roman.html
  • 1


#631277 C Program

Posted by dargueta on 07 June 2012 - 12:08 PM

As a general rule we don't do your homework for you. Can you show us some of your code or explain what your thought process is?
  • 1




Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download