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