我的cpp文件中有一些类。
class F{
private:
int id;
float o;
float p;
float s;
static int next;
public:
F(double o, double s = 0.23, double p = 0.0):
id(next++), o(o),
p(p), s(s){}
};
int F::next = 0;
extern "C" float pod(F f);
int main(){
F bur(1000, 0.23, 100);
pod(bur);
return 0;
}
我试图将类对象bur
传递给我的asm文件中定义的函数pod
。但是我从这个类对象获取值时遇到了很大的问题。
在asm计划中,0.23
XMM1
,100
XMM2
1000
但我无法找到存储$this->set('answer',$query[0]['answers'][0]['id']);
的位置。
答案 0 :(得分:1)
我不知道你为什么在xmm2中看到100
,我怀疑这完全是巧合。查看结构传递方式的最简单方法是编译C ++代码。
删除了cruft后,我的编译器会这样做:
main:
.LFB3:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl _ZN1F4nextE(%rip), %edi # load F::next into edi/rdi
movq .LC3(%rip), %xmm0 # load { 0.23, 100 } into xmm0
leal 1(%rdi), %eax # store rdi + 1 into eax
movl %eax, _ZN1F4nextE(%rip) # store eax back into F::next
movabsq $4934256341737799680, %rax # load { 1000.0, 0 } into rax
orq %rax, %rdi # or rax into pre-increment F::next in rdi
call pod
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.LC3:
.quad 4497835022170456064
常量4497835022170456064
以十六进制为3E6B851F42C80000
,如果查看最重要的四个字节(3E6B851F
),则在解释为单精度时为0.23
float
,最不重要的四个字节(42C80000
)为100.0
。
同样,常量4934256341737799680
(十六进制447A000000000000
)的最重要的四个字节是1000.0
。
因此,bur.id
传递了bur.o
和rdi
,bur.p
传递了bur.s
,xmm0
传递了rdi
。
x86-64 abi reference中记录了这一原因。在极端总结中,因为第一个fwo字段足够小,混合类型和其中一个是整数,它们被传递到通用寄存器(float
是第一个通用参数寄存器),因为接下来的两个字段都是public class MainActivity extends AppCompatActivity {
private ListView lvPhone;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lvPhone = (ListView)findViewById(R.id.listPhone);
final List<PhoneBook> listPhoneBook = new ArrayList<PhoneBook>();
listPhoneBook.add(new PhoneBook(BitmapFactory.decodeResource(getResources(),R.drawable.image),"Contact_1","123456789","av1@gmail.com","1"));
listPhoneBook.add(new PhoneBook(BitmapFactory.decodeResource(getResources(),R.drawable.image),"Contact_2","123456789","av2@gmail.com","2"));
listPhoneBook.add(new PhoneBook(BitmapFactory.decodeResource(getResources(),R.drawable.image),"Contact_3","123456789","av3@gmail.com","3"));
final PhoneBookAdapter adapter = new PhoneBookAdapter(this, listPhoneBook);
lvPhone.setAdapter(adapter);
lvPhone.setItemsCanFocus(false);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final Dialog d = new Dialog(MainActivity.this);
d.setTitle("Login");
d.setCancelable(true);
d.setContentView(R.layout.account);
d.show();
Button button_close = (Button) d.findViewById(R.id.DCancel);
button_close.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
d.dismiss();
}
});
Button button_login = (Button) d.findViewById(R.id.DLogin);
button_login.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String mName = new String("Ciao");
String mPhone;
String mEmail;
String mID;
TextView TextName = (TextView) d.findViewById(R.id.DName);
TextView TextPhone = (TextView)d.findViewById(R.id.DPhone);
TextView TextEmail = (TextView)d.findViewById(R.id.DEmail);
TextView TextID = (TextView)d.findViewById(R.id.DID);
mName=TextName.getText().toString();
mPhone=TextPhone.getText().toString();
mEmail=TextEmail.getText().toString();
mID=TextID.getText().toString();
listPhoneBook.add(new PhoneBook(BitmapFactory.decodeResource(getResources(),R.drawable.image),mName,mPhone,mEmail,mID));
lvPhone.setAdapter(adapter);
d.dismiss();
}
});
}
});
lvPhone.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView TextName = (TextView) view.findViewById(R.id.tvName);
TextView TextPhone = (TextView)view.findViewById(R.id.tvPhone);
TextView TextEmail = (TextView)view.findViewById(R.id.tvEmail);
TextView TextID = (TextView)view.findViewById(R.id.tvID);
String tvName = new String(TextName.getText().toString());
String tvPhone = new String(TextPhone.getText().toString());
String tvEmail = new String(TextEmail.getText().toString());
String tvID = new String(TextID.getText().toString());
Toast.makeText(MainActivity.this, tvName, Toast.LENGTH_SHORT).show();
}
});
lvPhone.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
}
}
,它们在SSE寄存器中传递。
答案 1 :(得分:1)
您想要了解来自Agner here的调用约定编译。根据编译器,操作系统以及您是否使用32位64位,可能会发生不同的事情。 (见表5第7章)。
对于64位linux,例如,由于您的对象包含不同的值(参见表6),R
案例似乎适用:
如果大小不大于128位,则整个对象在整数寄存器和/或XMM寄存器中传输,否则在堆栈上传输。如果对象的每个64位部分仅包含float或double,则在XMM寄存器中传输;如果它包含整数类型或混合整数和float,则在整数寄存器中传输。可以将两个连续的浮点数打包到一个XMM寄存器的下半部分。
在您的情况下,该类适合128位。来自@CharlesBailey的实验说明了这种行为。根据惯例
...或在整数寄存器中,如果它包含整数类型或混合整数和浮点数。两个连续的浮点数可以打包到一个XMM寄存器的下半部分。示例:int和float:RDI。
第一个int注册rdi
应该id
和o
xmm0
应该包含p
和s
。
在xmm2中看到100
可能是初始化的副作用,因为它作为double传递给结构构造函数。