LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-05-2014, 06:41 AM   #1
mirage1993
Member
 
Registered: Feb 2014
Location: China
Distribution: CentOS6.4
Posts: 51

Rep: Reputation: Disabled
Question How to use constraints "m" in gcc inline assembly when I pass a string ?


In this program
Code:
char get_fs_byte(char * s)
{
        char c;

        __asm__("movb %%fs:%1, %0":"=r"(c):"m"(*s));

        return c;
}
and
this
Code:
char get_fs_byte(char * s)
{
        char c;

        __asm__("movb %%fs:%1, %0":"=r"(c):"m"(s));

        return c;
}
what is the difference between
Code:
"m"(*s)
and
Code:
"m"(s)
.

Last edited by mirage1993; 10-05-2014 at 07:08 AM.
 
Old 10-06-2014, 03:15 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Are you absolutely sure you want to do this? Your program will be dependent on one single platform and one single compiler.
 
Old 10-06-2014, 03:17 AM   #3
mirage1993
Member
 
Registered: Feb 2014
Location: China
Distribution: CentOS6.4
Posts: 51

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by NevemTeve View Post
Are you absolutely sure you want to do this? Your program will be dependent on one single platform and one single compiler.
In fact,I just want to know their difference .
 
Old 10-06-2014, 03:22 AM   #4
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Then, I suppose, you have learned these by heart:
http://www.ibiblio.org/gferg/ldp/GCC...bly-HOWTO.html
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
 
1 members found this post helpful.
Old 10-06-2014, 03:44 AM   #5
mirage1993
Member
 
Registered: Feb 2014
Location: China
Distribution: CentOS6.4
Posts: 51

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by NevemTeve View Post
I had read these before I posted this post.
when I use "m"(*s). I am confused . Is "%1" a pointer to a string or the first characters of a string ?
 
Old 10-06-2014, 04:00 AM   #6
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
And how did you try to debug it?
 
Old 10-06-2014, 01:51 PM   #7
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by mirage1993 View Post
what is the difference between
Code:
"m"(*s)
and
Code:
"m"(s)
.
Try disassembling the result and see.
 
1 members found this post helpful.
Old 10-07-2014, 07:58 AM   #8
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by ntubski View Post
Try disassembling the result and see.
The point of such a constraint is that usually it makes no difference in the generated code, but in some complicated situations (typically when the function containing it is inlined into a caller) it affects some transformation that the optimizer makes to a related piece of code.

I don't know those syntax details myself. I rarely use asm, and only for large enough chunks that grossly suppressing optimization of the bordering C++ code is easier and makes sense (compared to fine tuning the constraints).

For your suggestion to make sense, one would need to first have a very good understanding of the optimizer and then construct a much more complicated example in which the correct vs. incorrect syntax for the constraint makes a difference in the optimization of surrounding code (with the incorrect syntax either allowing an incorrect optimization or preventing a correct optimization).

Understanding the syntax specification would be better than such experimentation. I expect someone in this forum does understand those syntax details. I don't.
 
Old 10-07-2014, 08:50 AM   #9
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by johnsfine View Post
The point of such a constraint...
If you look closely at the question, the difference between the 2 cases is not the constraint, but the input:

Code:
"m"(*s)                               "m"(s)
push   %rbp                           push   %rbp
mov    %rsp,%rbp                      mov    %rsp,%rbp
mov    %rdi,-0x18(%rbp)               mov    %rdi,-0x18(%rbp)
mov    -0x18(%rbp),%rax             
mov    %fs:(%rax),%al                 mov    %fs:-0x18(%rbp),%al
mov    %al,-0x1(%rbp)                 mov    %al,-0x1(%rbp)
movzbl -0x1(%rbp),%eax                movzbl -0x1(%rbp),%eax
pop    %rbp                           pop    %rbp
retq                                  retq
 
Old 10-07-2014, 10:08 AM   #10
mirage1993
Member
 
Registered: Feb 2014
Location: China
Distribution: CentOS6.4
Posts: 51

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by ntubski View Post
If you look closely at the question, the difference between the 2 cases is not the constraint, but the input:

Code:
"m"(*s)                               "m"(s)
OK,OK.I have understand a little.
I write another program.
Code:
#include<stdio.h>
void main()
{
    char c;
    //int tmp;
    char *s="abcdefg";
    asm("movb %1,%0\n\t"
    :"=d"(c)
    :"m"(*s));
    printf("out:%c\n",c);
}
In this code , "%1" represent a character "a"
and in the next code
Code:
#include<stdio.h>
void main()
{
    //char c;
    int tmp;
    char *s="abcdefg";
    printf("%d\n",s);
    asm("movl %1,%0\n\t"
    :"=d"(tmp)
    :"m"(s));
    printf("out:%d\n",tmp);
}
"%1" represent a pointer to the string "abcdefg".In another words ,"%1" represent a pointer to 'a'.
Note:tmp==s

Besides,in the next code
Code:
#include<stdio.h>
void main()
{
    char c;
    //int tmp;
    char *s="abcdefg";
    //printf("%d\n",s);
    asm("movb %%ds:%1,%0\n\t"
    :"=d"(c)
    :"m"(*s));
    printf("out:%c\n",c);
}
"%1" represent an offset to "abcdefg".

So,in addition to passing information in registers, gcc can understand references to raw memory. This will expand to some more complex addressing mode within the asm string.See this http://locklessinc.com/articles/gcc_asm/

What the "%1" represent is not important, because it changes all the time relying on the addressing mode.

Am I right?

Thanks all the people!

Last edited by mirage1993; 10-07-2014 at 10:16 AM.
 
Old 10-10-2014, 10:27 PM   #11
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by mirage1993 View Post
Code:
    char *s="abcdefg";
    asm("movb %1,%0\n\t"
    :"=d"(c)
    :"m"(*s));
In this code , "%1" represent a character "a"
yes.

Quote:
and in the next code
Code:
    char *s="abcdefg";
    printf("%d\n",s);
    asm("movl %1,%0\n\t"
    :"=d"(tmp)
    :"m"(s));
"%1" represent a pointer to the string "abcdefg".In another words ,"%1" represent a pointer to 'a'.
yes.

Quote:
Besides,in the next code
Code:
    char *s="abcdefg";
    //printf("%d\n",s);
    asm("movb %%ds:%1,%0\n\t"
    :"=d"(c)
    :"m"(*s));
"%1" represent an offset to "abcdefg".
No, it represents 'a' again. Simply because *s == 'a'.

Quote:
This will expand to some more complex addressing mode within the asm string.See this http://locklessinc.com/articles/gcc_asm/

What the "%1" represent is not important, because it changes all the time relying on the addressing mode.
Note that by using "m" you force "%1" to be a memory reference, even when the value could go into (or is already in) a register.
 
Old 10-10-2014, 11:06 PM   #12
mirage1993
Member
 
Registered: Feb 2014
Location: China
Distribution: CentOS6.4
Posts: 51

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by ntubski View Post
No, it represents 'a' again. Simply because *s == 'a'.
But ,when I use "gcc example.c -S" to compile

Code:
movb %%ds:%1,%0
is compiled to
Code:
movb %ds:(%eax),%edx
why..
 
Old 10-11-2014, 06:33 AM   #13
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by mirage1993 View Post
Code:
movb %%ds:%1,%0
is compiled to
Code:
movb %ds:(%eax),%edx
why..
Notice the () around %eax where you did not have () around %1

%eax is s

(%eax) is *s

%1 is the whole expression (%eax) not just the register %eax

The only difference vs. the earlier *s example that you seem to understand is the %ds: but that makes no actual difference.

Last edited by johnsfine; 10-11-2014 at 06:35 AM.
 
Old 10-11-2014, 08:20 AM   #14
mirage1993
Member
 
Registered: Feb 2014
Location: China
Distribution: CentOS6.4
Posts: 51

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by johnsfine View Post
Notice the () around %eax where you did not have () around %1

%eax is s

(%eax) is *s

%1 is the whole expression (%eax) not just the register %eax

The only difference vs. the earlier *s example that you seem to understand is the %ds: but that makes no actual difference.
if (%eax) is 'a',
Code:
movb %%ds:%1,%0
means
Code:
movb %ds:a,%0
a little strange......
 
Old 10-11-2014, 01:01 PM   #15
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by mirage1993 View Post
if (%eax) is 'a',
Code:
movb %%ds:%1,%0
means
Code:
movb %ds:a,%0
No, you can't apply memory segments like that. If (%eax) is 'a' then %ds:(%eax) is also 'a' (because current OSes setup the memory segments to have no effect (except for the %fs is used for thread local variables, I think)). But regardless, the segment applies to the address not the value located at the address.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
MSVC => GCC inline assembly translation rlanger Programming 1 02-03-2009 10:06 AM
Is anyone having problems with "gcc 1st pass"??? Southpaw76 Linux From Scratch 7 09-25-2006 08:26 PM
inline assembly in gcc gursev Programming 2 03-04-2005 02:17 AM
problems with gcc inline assembly using xmm registers Y0jiMb0 Programming 3 12-05-2004 02:59 PM
subrouine_call in gcc inline assembly sakeeb Programming 4 08-15-2002 10:22 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:37 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration