Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

gcc inline assembly and BTS

kapustakapusta Member Posts: 5
Hi all,

I am not a x86 assembly programmer myself, however, I need atomic BTS in my C program. I've managed to write the following code, however, the return values are bogus. Any idea where the problem may be?

Thanks.

#include

bool bts (void *mem, int offset)
{
int old;
__asm__ volatile (
"xor %%ecx, %%ecx
"
"lock; bts %1, %2
"
"setc %%cl
"
"mov %%ecx, %%eax
"
: "=a" (old)
: "r" (offset), "m" (mem)
: "memory", "cc", "%ecx");
return old;
}

int main ()
{
unsigned char c = 5;

for (int offset = 0; offset != 8; offset++) {
int old = bts (&c, offset);
printf ("Bit %d has value %d
", offset, old);
}
return 0;
}

Comments

  • IDKIDK Member Posts: 1,784
    Please use code tags:
    [code]
    : #include
    :
    : bool bts (void *mem, int offset)
    : {
    : int old;
    : __asm__ volatile (
    : "xor %%ecx, %%ecx
    "
    : "lock; bts %1, %2
    "
    : "setc %%cl
    "
    : "mov %%ecx, %%eax
    "
    : : "=a" (old)
    : : "r" (offset), "m" (mem)
    : : "memory", "cc", "%ecx");
    : return old;
    : }
    :
    : int main ()
    : {
    : unsigned char c = 5;
    :
    : for (int offset = 0; offset != 8; offset++) {
    : int old = bts (&c, offset);
    : printf ("Bit %d has value %d
    ", offset, old);
    : }
    : return 0;
    : }
    [/code]

    Where do you initiate old in bts()?

    And what's BTS?

    Also, are you aware that you're kind of jumping one more for each loop?
    Indexes could be if just returning an index: 1 3 6 10 15 21 ...
  • kapustakapusta Member Posts: 5

    : Where do you initiate old in bts()?

    I might look like an idiot here, but I thought "=a" (old) means that the old would be retrieved from eax.

    : And what's BTS?

    Bit-test-and-set. Moves a bit on an certain offset from some base address into CF and sets the bit afterwards.

    : Also, are you aware that you're kind of jumping one more for each
    : loop?
    : Indexes could be if just returning an index: 1 3 6 10 15 21 ...

    Sorry. Are you speaking of the following loop (seems to be the only one in the code)? There's nothing special about it...

    for (int offset = 0; offset != 8; offset++) ...

    Martin

  • IDKIDK Member Posts: 1,784
    :
    : : Where do you initiate old in bts()?
    :
    : I might look like an idiot here, but I thought "=a" (old) means that
    : the old would be retrieved from eax.
    :

    I've never seen that syntax, it's no standard syntax, and thus shouldn't be used (unless I'm badly informed, which can be the case).

    Also I'm not familiar with the : between the ""...

    I actually saw the : before the lines as asm comments which are denoted by ; ...


    I would do it like this in intel asm syntax:
    [code]
    Intel syntax:
    mov [old], eax

    AT%T syntax:
    mov %eax, (old)
    [/code]

    Intel syntax is much cleaner, and can also be used by the as the assembler with two extra lines of code.
  • kapustakapusta Member Posts: 5
    : :
    : : : Where do you initiate old in bts()?
    : :
    : : I might look like an idiot here, but I thought "=a" (old) means that
    : : the old would be retrieved from eax.
    : :
    :
    : I've never seen that syntax, it's no standard syntax, and thus
    : shouldn't be used (unless I'm badly informed, which can be the case).
    :
    : Also I'm not familiar with the : between the ""...

    It's gcc inline assembly, if there is a better way to write inline assembly in gcc, go forth with it.

    : I would do it like this in intel asm syntax:
    : [code]:
    : Intel syntax:
    : mov [old], eax
    :
    : AT%T syntax:
    : mov %eax, (old)
    : [/code]:
    :
    : Intel syntax is much cleaner, and can also be used by the as the
    : assembler with two extra lines of code.

    Intel or AT&T syntax, it doesn't really matter. All whay I need is to execute atomic BTS from C.
  • kapustakapusta Member Posts: 5
    Ok, I've made a new version of the code:

    [code]
    #include

    bool bts (volatile void *mem, int offset)
    {
    int old;
    __asm__ volatile (
    "lock; bts %1, %2
    "
    "setc %%al
    "
    "movzb %%al, %0
    "
    : "=r" (old)
    : "r" (offset), "m" (mem)
    : "memory", "cc", "%eax");
    return old;
    }

    int main ()
    {
    volatile unsigned char c = 5;

    for (int offset = 0; offset != 7; offset++) {
    int old = bts (&c, offset);
    printf ("Bit %d has value %d
    ", offset, old);
    }
    printf ("The value of c is: %d
    ", (int) c);
    return 0;
    }
    [/code]

    Here's the disassebly of the bts function:

    [code]
    08048418 <_Z3btsPVvi>:
    8048418: 55 push %ebp
    8048419: 89 e5 mov %esp,%ebp
    804841b: 83 ec 10 sub $0x10,%esp
    804841e: 8b 55 0c mov 0xc(%ebp),%edx
    8048421: f0 0f ab 55 08 lock bts %edx,0x8(%ebp)
    8048426: 0f 92 c0 setb %al
    8048429: 0f b6 d0 movzbl %al,%edx
    804842c: 89 55 fc mov %edx,0xfffffffc(%ebp)
    804842f: 83 7d fc 00 cmpl $0x0,0xfffffffc(%ebp)
    8048433: 0f 95 c0 setne %al
    8048436: 0f b6 c0 movzbl %al,%eax
    8048439: c9 leave
    804843a: c3 ret
    804843b: 90 nop
    [/code]

    Still, the results are bogus. Thoughts?

    Martin
  • kapustakapusta Member Posts: 5
    Finally, after 8 hours of desperate experimenting, here's the code that works:

    [code]
    bool bts (volatile void *mem, int offset)
    {
    int old;
    __asm__ volatile (
    "lock; bts %1, (%2)
    "
    "setc %%al
    "
    "movzb %%al, %0
    "
    : "=r" (old)
    : "r" (offset), "r" (mem)
    : "memory", "cc", "%eax");
    return old;
    }
    [/code]
Sign In or Register to comment.