2017-08-10 57 views
3

我試圖使用這個建議針對此問題x86-64 Linux NASM。功能參數傳遞int類型陣列的聲明爲在C++中的函數文件

For Linux programming arr[], n, &a, &b are passed in RDI, RSI, RDX and RCX.

和程序的輸出陣列中不總結整數正確。它輸出一個明顯錯誤的大數字。

下面找到的兩個文件是從這裏找到的原始32位版本進行修改的。 http://mcs.uwsuper.edu/sb/224/Intro/c_asm.html

我要的是編譯調用名爲array.cpp一個C++文件中的函數參數,然後鏈接生成的目標文件array.og++彙編文件。

我遇到的問題與將正確的寄存器傳遞到堆棧上或者可能爲rsi寄存器上的每個偏移量添加的字節數(我使用了8,因爲每個堆棧元素都是64位)。

它也可以是,所述rbp寄存器沒有正確裝載在陣列地址編號的數組元素中的的正確的偏移量。

mov rcx, [rbp+24] ; array length 
mov rsi, [rbp+16] ; array address 

不管怎麼說,這裏的array.cpp文件和它下面是NASM文件,我把它叫做nasm_cpp.asm

他們編譯,鏈接並運行

nasm -f elf64 nasm_cpp.asm -o array.o 
g++ -m64 array.cpp array.o 
./a.out 


#include <iostream> 
using namespace std; 

extern "C" int array(int a[], int length); // external ASM procedure 

int main() 
{ 
    int a[] = { 10, 10}; // array declaration 
    int array_length = 2;      // length of the array 

    int sum = array(a, array_length);   // call of the ASM procedure 

    cout << "sum=" << sum << endl;    // displaying the sum 
} 

這是nasm_cpp.asm低於

;nasm -f elf64 nasm_cpp.asm -o array.o 
;g++ -m64 array.cpp array.o 
;./a.out 
global array    ; required for linker and NASM 
section .text    ; start of the "CODE segment" 

array: push rbp   
     mov rbp, rsp  ; set up the rBP 
     push rcx   ; save used registers 
     push rdi 
     push rsi 

     mov rcx, [rbp+24] ; array length 
     mov rsi, [rbp+16] ; array address 

     xor rax, rax  ; clear the sum value  
lp: add rax, [rsi]  ; fetch an array element 
     add rsi, 8   ; move to another element 
     loop lp    ; loop over all elements 

     pop rsi    ; restore used registers 
     pop rdi 
     pop rcx  
     pop rbp 
     ret     ; return to caller 
+2

參數在x86-64寄存器中傳遞。谷歌的「SYS V ABI x64」 –

+0

這裏http://wiki.osdev.org/System_V_ABI它說'函數的參數在寄存器rdi,rsi,rdx,rcx,r8,r9,'中傳遞。這是你認爲可能解決的問題嗎?那麼'rcx' reg呢?我應該如何計算並在堆棧推入之前將值保存在它中? – pandoragami

+0

我刪除了'rcx'' push'和'pop',但仍然無法工作。 – pandoragami

回答

1

我跟着貼出的問題下面的意見建議和現在的工作,cpp文件與上述相同。

;nasm -f elf64 nasm_cpp.asm -o array.o 
;g++ -m64 array.cpp array.o 
;./a.out 
global array    ; required for linker and NASM 
section .text    ; start of the "CODE segment" 

array:  
     push rbp   
     mov rbp, rsp  ; set up the rBP 

     mov rcx, rsi ; array length 
     mov rsi, rdi ; array address 

     xor rax, rax  ; clear the sum value  
lp: add eax, [rsi]  ; fetch an array element 
     add rsi, 4   ; move to another element 
     loop lp    ; loop over all elements  

     pop rbp 

     ret     ; return to caller 
+2

注意你的如果數組長度爲零,代碼將不起作用。這是否是一個問題取決於您的規格。 – Jester

+0

我想我可以在'cmp rcx,0'之後添加'jz outside_loop'條件嗎? – pandoragami

+1

還有'jecxz'指令 – Jester

相關問題