臂;内联asm;使用临时寄存器;

时间:2016-07-21 01:53:42

标签: gcc assembly arm inline-assembly

我无法理解内联汇编程序存在的一些问题。

我有一个内联汇编程序的函数。在ASM块内部,我需要使用一些临时寄存器来修改某些系统值。

void setHW(uint32_t val) {
    asm volatile (
        mrc 15, 0, r0, ...
        orr r0, r0, %0 
        mcr 15, 0, r0, ...
        : :"r"(val) :"r0"
    );
}

实际上函数是由编译器内联的,没关系,代码仍然运行良好。

当我尝试用一​​些存根变量替换硬编码的r0时出现问题,因此编译器可以选择最好的寄存器来使用。看起来像这样

void setHW(uint32_t val) {
    uint32_t reg;
    asm volatile (
        mrc 15, 0, %[reg], ...
        orr %[reg], %[reg], %0 
        mcr 15, 0, %[reg], ...
        :[reg]"=r"(reg) :"r"(val) :
    );
}

现在编译器自己选择注册,但实际上会破坏setHW调用函数的值。 在反汇编程序中它看起来像

        add r2, r4, r5       ; caller part, r2 contain some intermedia result
        mrc 15, 0, r2, ...   ; inlined setHW(), r2 is choosen as scratch reg
        orr r2, r2, r0 
        mcr 15, 0, r2, ...
        ; caller continue

正如您所看到的,r2已损坏且一切都崩溃了。

如何定义临时寄存器以避免这种情况?

1 个答案:

答案 0 :(得分:4)

这样的事情怎么样:

&

请注意 @Controller @SessionAttributes("name") public class LoginController { @RequestMapping(value = "/login", method = RequestMethod.POST) public String handleUserLogin(ModelMap model, @RequestParam String name) { model.addAttribute("name", name); return "login"; } } 以修复早期的clobber问题(有关public class Tutorial1Activity extends Activity implements CvCameraViewListener2 { private static final String TAG = "OCVSample::Activity"; private CameraBridgeViewBase mOpenCvCameraView; private boolean mIsJavaCamera = true; private MenuItem mItemSwitchCamera = null; //*****************writetoSD***********************// public FileWriter fw; // = new FileWriter(folder_path, false); public BufferedWriter bw;// = new BufferedWriter(fw); boolean first_in = true; String showTimefile = null; String showTime = null; String folder_path = Environment.getExternalStorageDirectory().getAbsolutePath(); String folder_name = "Face Detection Signal"; String folder_pathforfile = null; SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH_mm_ss"); SimpleDateFormat sdf_fileintxt = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); //*****************writetoSD***********************// //---------------MediaRecorder-------------------// public MediaRecorder mediaRecorder; Button bt_Record; boolean isRecord = false; Handler mThreadHandler; HandlerThread mHandlerThread; //---------------MediaRecorder-------------------// private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { @Override public void onManagerConnected(int status) { switch (status) { case LoaderCallbackInterface.SUCCESS: { Log.i(TAG, "OpenCV loaded successfully"); mOpenCvCameraView.enableView(); } break; default: { super.onManagerConnected(status); } break; } } }; public Tutorial1Activity() { Log.i(TAG, "Instantiated new " + this.getClass()); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { Log.i(TAG, "called onCreate"); super.onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.tutorial1_surface_view); mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view); mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); mOpenCvCameraView.setCvCameraViewListener(this); //---------------------------------------------------------// bt_Record = (Button)findViewById(R.id.bt_recorder); folder_pathforfile = folder_path + File.separator + folder_name + File.separator + "opencv" + "_"; CreateSDfolder(); ongetTime(); //---------------------------------------------------------// } @Override public void onPause() { super.onPause(); if (mOpenCvCameraView != null) mOpenCvCameraView.disableView(); } @Override public void onResume() { super.onResume(); if (!OpenCVLoader.initDebug()) { Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization"); OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback); } else { Log.d(TAG, "OpenCV library found inside package. Using it!"); mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS); } } public void onDestroy() { super.onDestroy(); if (mOpenCvCameraView != null) mOpenCvCameraView.disableView(); } public void onCameraViewStarted(int width, int height) { } public void onCameraViewStopped() { } public Mat onCameraFrame(CvCameraViewFrame inputFrame) { return inputFrame.rgba(); } private void CreateSDfolder() { String filefolderpath = folder_path + File.separator + folder_name; File dir = new File(filefolderpath); if (!dir.exists()){ Log.e("folder", "not exist"); try{ //dir.createNewFile(true); dir.mkdir(); Log.e("folder", "creat exist"); }catch(Exception e){ Log.e("folder", "creat not exist"); e.printStackTrace(); } } else{ Log.e("folder", "exist"); } } private void ongetTime() { Date dt=new Date(); showTime=sdf_fileintxt.format(dt); showTimefile =sdf.format(dt); } private void WritetoSD(String data) { try { fw = new FileWriter(folder_pathforfile + showTimefile+".txt", true); bw = new BufferedWriter(fw); if (first_in == true) { first_in = false; bw.append(showTime); bw.newLine(); } bw.append(data); bw.newLine(); bw.flush(); bw.close(); } catch (IOException e) { Log.e("WriteToSD", "Write To SD ERROR"); e.printStackTrace(); } } public void onRecordSignal (View v){ if(!isRecord){ isRecord = true; Log.e(TAG, "button click " + isRecord); bt_Record.setText("Stop"); //new MediaPrepareTask().execute(null, null, null); if (prepareMediaRecorder()) { // Camera is available and unlocked, MediaRecorder is prepared, // now you can start recording Log.e("debug_mediarecorder", "prepareMediaRecorder in if"); mOpenCvCameraView.setRecorder(mediaRecorder); mediaRecorder.start(); } else { // prepare didn't work, release the camera Log.e("debug_mediarecorder", "prepareMediaRecorder in else"); // mediaRecorder.stop(); releaseMediaRecorder(); } } else{ isRecord = false; Log.e(TAG, "button click " + isRecord); bt_Record.setText("Record"); try { if(mediaRecorder != null) mediaRecorder.stop(); // stop the recording else Log.e(TAG,"onRecordSignal mediaRecorder is null"); } catch (RuntimeException e) { // RuntimeException is thrown when stop() is called immediately after start(). // In this case the output file is not properly constructed ans should be deleted. Log.d(TAG, "RuntimeException: stop() is called immediately after start()"); //noinspection ResultOfMethodCallIgnored } releaseMediaRecorder(); // release the MediaRecorder object } } public void releaseMediaRecorder() { Log.e("debug","releaseMediaRecorder"); if (mediaRecorder != null) { mediaRecorder.reset(); // clear recorder configuration mediaRecorder.release(); // release the recorder object mediaRecorder = null; JavaCameraView.mCamera.lock(); mOpenCvCameraView.releaseRecord(); } } private String recordfilepath() { // TODO Auto-generated method stub ongetTime(); File sddir = Environment.getExternalStorageDirectory(); File vrdir = new File(sddir, folder_name); File file = new File(vrdir, showTimefile+"_.mp4"); String filepath = file.getAbsolutePath(); Log.e("debug mediarecorder", filepath); return filepath; } public boolean prepareMediaRecorder() { // TODO Auto-generated method stub Log.e("debug mediarecorder", "in prepareMediaRecorder"); mediaRecorder = new MediaRecorder(); try { JavaCameraView.mCamera.lock(); JavaCameraView.mCamera.unlock(); }catch (RuntimeException e){ Log.e("debug mediarecorder","JavaCameraView.mCamera.unlock() fail"); } /*mediaRecorder.reset(); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); //mediaRecorder.setPreviewDisplay(CameraBridgeViewBase.mSurfaceHolder.getSurface()); mediaRecorder.setOutputFile(recordfilepath()); //mediaRecorder.setOnInfoListener((MediaRecorder.OnInfoListener) this); //mediaRecorder.setOnErrorListener((MediaRecorder.OnErrorListener) this);*/ mediaRecorder.reset(); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); CamcorderProfile cpHigh = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH); mediaRecorder.setProfile(cpHigh); //mediaRecorder.setOutputFile("out.mp4"); mediaRecorder.setOutputFile(recordfilepath()); mediaRecorder.setVideoSize(mOpenCvCameraView.mFrameWidth, mOpenCvCameraView.mFrameHeight); //mediaRecorder.setOnInfoListener(this); //mediaRecorder.setOnErrorListener(this); try { mediaRecorder.prepare(); } catch (IllegalStateException e) { Log.e("debug mediarecorder", "not prepare"); releaseMediaRecorder(); return false; } catch (IOException e) { Log.e("debug mediarecorder", "not prepare IOException"); //releaseMediaRecorder(); } return true; } } 的说明,请参阅https://gcc.gnu.org/onlinedocs/gcc/Modifiers.html。)