用户输入和输出在我的汇编代码中不起作用

时间:2016-03-19 15:57:25

标签: macos assembly x86 nasm

以下程序编译时没有错误,但在运行时它不会提示任何输入,也不会打印任何内容。问题是什么,我该如何解决?

我使用这些命令来汇编和链接:

 <?php 
 if($_SERVER['REQUEST_METHOD']=='POST'){

    $photo= $_POST['photo'];
    $bookname=$_POST['bookname'];
            $phoneNumber=$_POST['phoneNumber'];
            $price=$_POST['price'];

    require_once('loginConnect.php');

    $sql ="SELECT id FROM images ORDER BY id ASC";

    $res = mysqli_query($con,$sql);

    $id = 0;

    while($row = mysqli_fetch_array($res)){
            $id = $row['id'];
    }

    $path = "uploads/$id.png";

    $actualpath = "http://www.bsservicess.com/photoUpload/$path";

    $sql = "INSERT INTO images (photo,bookname,phoneNumber,price) VALUES
     ('$actualpath','$bookname','$phoneNumber','$price')";

    if(mysqli_query($con,$sql)){
        file_put_contents($path,base64_decode($photo));
        echo "Successfully Uploaded";
    }

    mysqli_close($con);
  }else{
    echo "Error";
 }
?


 enter code here> Blockquote

   package com.manali.vivek.userregistration;

   import android.app.ProgressDialog;
   import android.content.Intent;
   import android.graphics.Bitmap;``
   import android.net.Uri;
   import android.os.AsyncTask;
   import android.os.Bundle;
   import android.provider.MediaStore;
   import android.support.v7.app.ActionBarActivity;
   import android.util.Base64;
   import android.view.View;
   import android.widget.Button; 
   import android.widget.EditText;
   import android.widget.ImageView;
   import android.widget.Toast;

   import java.io.ByteArrayOutputStream;
   import java.io.IOException;
   import java.util.HashMap;


 public class image extends ActionBarActivity implements
  View.OnClickListener    
 {

   public static final String UPLOAD_URL =
    "http://www.bsservicess.com/photoUpload/uploadImage.php";
   public static final String UPLOAD_KEY = "image";

   private int PICK_IMAGE_REQUEST = 1;

   private Button buttonChoose;
   private Button buttonUpload;
   private Button buttonView;

   private ImageView imageView;

   private Bitmap bitmap;

   private Uri filePath;
   EditText et1,et2,et3;

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_image);

    buttonChoose = (Button) findViewById(R.id.buttonChoose);
    buttonUpload = (Button) findViewById(R.id.buttonUpload);
    buttonView = (Button) findViewById(R.id.buttonViewImage);
    et1=(EditText)findViewById(R.id.et1);
    et2=(EditText)findViewById(R.id.et2);
    et3=(EditText)findViewById(R.id.et3);
    imageView = (ImageView) findViewById(R.id.imageView);

    buttonChoose.setOnClickListener(this);
    buttonUpload.setOnClickListener(this);
    buttonView.setOnClickListener(this);
  }

  private void showFileChooser() {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), 
 PICK_IMAGE_REQUEST);
 }

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent 
  data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data
   != null && data.getData() != null) {

        filePath = data.getData();
        try {

            bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),   
       filePath);
            imageView.setImageBitmap(bitmap);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   }

   public String getStringImage(Bitmap bmp){
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] imageBytes = baos.toByteArray();


   String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
    return encodedImage;
   }


   private void uploadImage(){


        class UploadImage extends AsyncTask<Bitmap,Void,String>{

        ProgressDialog loading;
        RequestHandler rh = new RequestHandler();

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            loading = ProgressDialog.show(image.this, "Uploading Image",
         "Please wait...",true,true);
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            loading.dismiss();

         Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
        }

        @Override
        protected String doInBackground(Bitmap... params) {

            Bitmap bitmap = params[0];
            String uploadImage = getStringImage(bitmap);
            String bookname=et1.getText().toString();
            String  phoneNumber=et2.getText().toString();
            String price=et3.getText().toString();

            HashMap<String,String> data = new HashMap<>();
            data.put(UPLOAD_KEY, uploadImage);

            data.put(Fetch.BOOK_NAME,bookname);
            data.put(Fetch.PHONE_NUMBER,phoneNumber);
            data.put(Fetch.PRICE,price);



            String result = rh.sendPostRequest(UPLOAD_URL,data);

            return result;
        }

    }

    UploadImage ui = new UploadImage();

    ui.execute(bitmap);


    }







 @Override
  public void onClick(View v) {
    if (v == buttonChoose) {
        showFileChooser();
    }
    if(v == buttonUpload){
    uploadImage();

    }


    if(v == buttonView){
        viewImage();
    }
  }


private void viewImage() {
    startActivity(new Intent(image.this, Main.class));
     }
 }

我的代码是:

/usr/local/bin/nasm -f macho32 $1
ld -macosx_version_min 10.9.0 -lSystem -o run $filename.o -e _start -lc

1 个答案:

答案 0 :(得分:5)

您的代码中有迹象表明您在为OS / X(BSD)生成代码时可能一直在使用Linux教程。 Linux和OS / X具有不同的 SYSCALL 调用约定。在OS / X中,32位程序int 0x80需要在堆栈上传递参数( EAX 中的系统调用除外)。

在OS / X上通过int 0x80了解32位 SYSCALL 的重要事项是:

  
      
  • 在堆栈上传递的参数,从右向左推送
  •   
  • 在推送所有参数后,必须在堆栈上再分配4个字节( DWORD
  •   
  • eax寄存器中的系统调用号
  •   
  • 通过中断0x80调用
  •   

int 0x80以相反的顺序在堆栈上推送参数后,必须在堆栈上分配额外的4个字节( DWORD )。堆栈中该内存位置的值并不重要。此要求是来自old UNIX convention的工件。

可以在 APPLE header files中找到 SYSCALL 编号及其参数的列表。您需要这些 SYSCALL

1 AUE_EXIT    ALL { void exit(int rval); }
3 AUE_NULL    ALL { user_ssize_t read(int fd, user_addr_t cbuf, user_size_t nbyte); } 
4 AUE_NULL    ALL { user_ssize_t write(int fd, user_addr_t cbuf, user_size_t nbyte); } 

我已经评论了一些示例代码,这些代码的功能与您尝试实现的功能类似:

section .data
    ;New line string
    NEWLINE: db 0xa, 0xd
    LENGTH: equ $-NEWLINE

section .bss
    INPT: resd 1

global _start

section .text
_start:
    and     esp, -16      ; Make sure stack is 16 byte aligned at program start
                          ;     not necessary in this example since we don't call 
                          ;     external functions that conform to the OS/X 32-bit ABI

    push    dword 1       ; Read 1 character
    push    dword INPT    ; Input buffer
    push    dword 0       ; Standard input = FD 0
    mov     eax, 3        ; syscall sys_read
    sub     esp, 4        ; Extra 4 bytes on stack needed by int 0x80
    int     0x80
    add     esp, 16       ; Restore stack

    push    dword 1       ; Print 1 character
    push    dword INPT    ; Output buffer = buffer we read characters into
    push    dword 1       ; Standard output = FD 1
    mov     eax, 4        ; syscall sys_write
    sub     esp, 4        ; Extra 4 bytes on stack needed by int 0x80
    int     0x80
    add     esp, 16       ; Restore stack

    push    dword LENGTH  ; Number of characters to write
    push    dword NEWLINE ; Write the data in the NEWLINE string
    push    dword 1       ; Standard output = FD 1
    mov     eax, 4        ; syscall sys_write
    sub     esp, 4        ; Extra 4 bytes on stack needed by int 0x80
    int     0x80
    add     esp, 16       ; Restore stack

    push    dword 0       ; Return value from program = 0
    mov     eax, 1        ; syscall sys_exit
    sub     esp, 4        ; Extra 4 bytes on stack needed by int 0x80
    int     0x80

只有在需要将堆栈与16字节边界对齐作为未来堆栈操作的基线时,才需要and esp, -16。如果您打算调用符合OS/X 32-bit ABI的外部函数,则堆栈应在函数 CALL 之前立即对齐16字节。通过int 0x80进行系统调用不需要此对齐。

您应该能够将其组合并链接到:

nasm -f macho32 test.asm -o test.o
ld -macosx_version_min 10.9.0 -o test test.o -e _start -lSystem

运行它:

./test