有时gcc会在编译arm abi的C ++代码时将第一个参数放入R1寄存器中吗?

时间:2015-12-04 07:10:56

标签: android gcc assembly arm

从ARM到C调用约定,我知道参数是从寄存器r0-r4开始按顺序传递的,然后是其他参数堆栈的使用。返回值传递给r0-r1。

但是在libart.so(AndroidM,/ system / lib / libart.so,32bit)中,有一种方法似乎与规则不匹配。

//https://android.googlesource.com/platform/art/+/android-6.0.0_r5/runtime/oat_file.cc
std::unique_ptr<const DexFile> OatFile::OatDexFile::OpenDexFile(std::string* error_msg) const {
    return DexFile::Open(dex_file_pointer_, FileSize(), dex_file_location_,
                       dex_file_location_checksum_, this, error_msg);
}

//https://android.googlesource.com/platform/art/+/android-6.0.0_r5/runtime/dex_file.h
static std::unique_ptr<const DexFile> DexFile::Open(const uint8_t* base, size_t size,
                                             const std::string& location,
                                             uint32_t location_checksum,
                                             const OatDexFile* oat_dex_file,
                                             std::string* error_msg) {
    return OpenMemory(base, size, location, location_checksum, nullptr, oat_dex_file, error_msg);
}

OpenDexfile是OatDexFile类的一个memeber函数,它是OatFile类的内部类。所以OpenDexFile实际上有2个参数,因为第一个参数是&#34;这个&#34;。 但在IDA Pro中,OpenDexFile如下所示:

.text:002E9718 var_14          = -0x14
.text:002E9718 var_4           = -4
.text:002E9718
.text:002E9718   STR.W           R4, [SP,#var_14]!
.text:002E971C   MOV             R4, R1   ;<<--After analysing, I can assure that R1 is the "this" pointer
.text:002E971E   LDR             R1, [R1,#0x20] ;<<---dex_file_pointer
.text:002E9720   STRD.W          R5, R6, [SP,#4]
.text:002E9724   ADDS            R3, R4, #4
.text:002E9726   MOV             R5, R0 ;<<---It seems like that r0 is added but not for the "this" pointer
.text:002E9728   STRD.W          R7, LR, [SP,#0xC]
.text:002E972C   LDR.W           LR, [R4,#0x1C]
.text:002E9730   SUB             SP, SP, #0x14
.text:002E9732   MOVS            R7, #0
.text:002E9734   LDR             R6, [R1,#0x20]
.text:002E9736   STRD.W          R4, R2, [SP,#8]  ;<<--R2 represent the arg "error_msg"
.text:002E973A   STRD.W          LR, R7, [SP]
.text:002E973E   MOV             R2, R6
.text:002E9740   BL     DexFile::OpenMemory ;<<---DexFile::Open is a inline function. When executing this instruction, r0 equals r5.
.text:002E9744   MOV             R0, R5;<<--OpenMemory is also a bit weird. It looks like that OpenMemory also adds r0 for the return value, because r0 equals r5 before calling OpenMemory
.text:002E9746   ADD             SP, SP, #0x14
.text:002E9748   LDRD.W          R4, R5, [SP]
.text:002E974C   LDRD.W          R6, R7, [SP,#8]
.text:002E9750   ADD             SP, SP, #0x10
.text:002E9752   LDR.W           PC, [SP+4+var_4],#4

我只是想知道是否存在特殊情况&#34;这个&#34;指针将被放入R1而不是R0,并且从寄存器r1开始按顺序传递这些指针。 如果你能帮助我,我将不胜感激。

2 个答案:

答案 0 :(得分:0)

来自Procedure Call Standard

  

如果子程序是一个在内存中返回结果的函数,那么   结果的地址放在r0中,NCRN设置为r1。

OpenDexFile

(可能)返回一个需要放置内存的DexFile对象,因此r0r1变为this

之前已经讨论过这个问题:the order of C++ implicit arguments: this and the returned object, which goes first?

一般说明ARM ABI类似于Itanium ABI。如果您在检查ARM ABI后找到要研究的来源时遇到问题,您也可以查看那个。

答案 1 :(得分:-3)

检查arm ABI第5.5章

R0:返回值

R1-R3加堆栈:用于传递参数