2013-07-25 74 views
3

我寫了一個程序,該程序的行爲應該與 while循環一樣,打印一定數量的文本字符串。int 0x80是否覆蓋寄存器值?

下面是代碼:

global _start 


    section .data 

    msg db "Hello World!",10 ; define the message 
    msgl equ $ - msg   ; define message length 
           ; use minimal size of storage space 

    imax dd 0x00001000   ; defines imax to be big! 

    section .text 
_start: 


    mov r8, 0x10   ; <s> put imax in r8d, this will be our 'i' </s> 
          ; just attempt 10 iterations 
_loop_entry:     ; loop entry point 
    mov eax, 4     ; setup the message to print 
    mov ebx, 1     ; write, stdout, message, length 
    mov ecx, msg 
    mov edx, msgl 
    int 0x80     ; print message 
           ; this is valid because registers do not change 
    dec r8      ; decrease i and jump on not zero 
    cmp r8,1     ; compare values to jump 
    jnz _loop_entry 


    mov rax, 1     ; exit with zero 
    mov rbx, 0 
    int 0x80 

我的問題是程序運行到一個無限循環。我在gdb中運行它,原因是:

int 0x80被調用來打印消息,並且這個工作正常,但是在中斷完成後,r8的內容被設置爲零,而不是它應該是的值。 r8是計數器坐落的位置,計數(減少)字符串打印的次數。

int 0x80是否修改寄存器值?我注意到rax,rbx,rcx,rdx沒有以同樣的方式受到影響。

測試結果

回答:是的!它會修改r8。

我改變了我的程序中的兩件事。首先我現在cmp r8, 0,以獲得Hello World!正確的次數,並

我已經加入

mov [i], r8     ; put away i 

_loop_entry:

後還我已經第一int 0x80後添加

mov r8, [i]     ; get i back 

這是我現在的工作計劃。更多關於C++性能的信息。

; 
; main.asm 
; 
; 
; To be used with main.asm, as a test to see if optimized c++ 
; code can be beaten by me, writing a for/while loop myself. 
; 
; 


; Absolute minimum code to be competative with asm. 


global _start 


    section .data 

    msg db "Hello World!",10 ; define the message 
    msgl equ $ - msg   ; define message length 
           ; use minimal size of storage space 

    imax dd 0x00001000   ; defines imax to be big! 
    i dd 0x0     ; defines i 

    section .text 
_start: 


    mov r8, 0x10   ; put imax in r8d, this will be our 'i' 
_loop_entry:     ; loop entry point 
    mov [i], r8     ; put away i 
    mov eax, 4     ; setup the message to print 
    mov ebx, 1     ; write, stdout, message, length 
    mov ecx, msg 
    mov edx, msgl 
    int 0x80     ; print message 
           ; this is valid because registers do not change 
    mov r8, [i]     ; get i back 
    dec r8      ; decrease i and jump on not zero 
    cmp r8,0     ; compare values to jump 
    jnz _loop_entry 


    mov rax, 1     ; exit with zero 
    mov rbx, 0 
    int 0x80 
+0

可能重複[在x86-64上UNIX和Linux系統調用的調用約定是什麼](http://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix- linux-system-calls-on-x86-64) –

回答

6

int 0x80只是引起軟件中斷。在你的情況下,它被用來進行系統調用。是否影響任何寄存器將取決於您所調用的特定系統調用以及您的平臺的系統調用調用約定。閱讀您的文檔以獲取詳細信息。

具體而言,從系統V應用程序二進制接口X86-64 ™架構處理器補充 [PDF link],附錄A,X86-64 Linux內核約定

C庫之間的接口並且Linux內核與用戶級應用程序相同...

對於用戶級應用程序,r8是一個臨時寄存器,這意味着它的呼叫者保存。如果您希望通過系統調用保留它,您需要自己做。

+0

好吧,作爲一個測試,我將保存並將r8恢復到int 0x80的任意一側。我會更新你 – user3728501