2013-07-25 2 views
3

Я написал программу, которая должна вести себя как для while loop, печатая строку текста определенное количество раз.Записывает ли регистры значения 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 - это где счетчик сидит, подсчитывая (вниз) количество строк, которые печатаются в строке.

Does int 0x80 изменить значения регистра? Я заметил, что rax, rbx, rcx, rdx не были затронуты одинаково.

Результаты тестов

Ответ: ДА! Он модифицирует r8.

Я изменил две вещи в своей программе. Сначала я сейчас cmp r8, 0, чтобы получить Hello World! правильное число раз, а

Я добавил

mov [i], r8     ; put away i 

После _loop_entry:

, а также я добавил

mov r8, [i]     ; get i back 

после первого int 0x80.

Вот моя работающая программа. Больше информации о производительности на 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

Возможный дубликат [Что такое вызывающие соглашения для системных вызовов UNIX и Linux на x86-64] (http://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix- linux-system-calls-on-x86-64) –

ответ

6

int 0x80 просто вызывает прерывание программного обеспечения. В вашем случае он используется для системного вызова. Независимо от того, будут ли затронуты какие-либо регистры, будет зависеть конкретный вызов системы, который вы вызываете, и соглашение о вызове системы на вашей платформе. Прочтите документацию для получения подробной информации.

В частности, из системы V Application Binary Interface x86-64 ™ архитектуры процессора Supplement [PDF link], Приложение A, x86-64 Linux Kernel конвенции:

Интерфейс между библиотекой C и ядро ​​Linux такое же, как для приложений пользовательского уровня ...

Для приложений пользовательского уровня r8 является регистром царапин, что означает, что он сохранен. Если вы хотите, чтобы он был сохранен по системному вызову, вам нужно будет сделать это самостоятельно.

+0

Хорошо, в качестве теста я буду сохранять и восстанавливать r8 в память по обе стороны от int 0x80. Я обновлю вас – user3728501

Смежные вопросы