Я пытаюсь немного изучить ассемблер. Я использую NASM вместо синтаксиса AT & T.
Это моя первая программа, она сравнивает два аргумента командной строки и выводит, какой из них наименьший (предпочтительнее первого в случае, если они равны).
Я думаю, что я делаю это неправильно. Я заметил, что стек растет с каждым «вызовом» сравнения, поэтому я мог бы сделать это лучше с оптимизацией хвостовой рекурсии. Однако я не знаю, как это сделать правильно. Должен ли я заменить все вхождения 'call' здесь чем-то другим, например, jmp?
Я читал, что способ перехода также зависит от того, как вы связываетесь с ядром linux и / или libc относительно объектов 'function' (я не связываюсь с libc и поэтому не имею основной 'function'), что меня смущает, поэтому я думал, что приду сюда за простым кратким советом.
Кроме того, еще один вопрос, который у меня возник, заключается в том, насколько глупо делать «jl» сразу после «jg», что может вызвать нежелательное поведение, если переход «jl» фактически изменил содержимое флага, поэтому «jg» также переходит. Есть ли двусторонний «атомный» прыжок?
section .data
usage: db 'Please provide two strings',10
usageLen: equ $-usage
bigger: db 'It is bigger!',10
biggerLen: equ $-bigger
smaller: db 'It is smaller!',10
smallerLen: equ $-smaller
section .text
global _start
_start:
pop ebx ; argc
cmp ebx, 3
jne usage_exit
pop eax ; argv[0]
pop eax
pop ebx
call compare ;
usage_exit:
mov eax, 4 ; sys_write
mov ebx, 1 ; int fd = stdout
mov ecx, usage
mov edx, usageLen
int 80h ; call kernel
mov eax, 1 ; sys_exit
mov ebx, 0 ; int status = 0
int 80h ; call kernel
report:
mov ecx, eax
mov edx, ebx
mov eax, 4 ; sys_write
mov ebx, 1 ; int fd = stdout
int 80h ; call kernel
mov eax, 1 ; sys_exit
mov ebx, 0 ; int status = 0
int 80h ; call kernel (exit)
compare:
push eax
push ebx
mov eax, [eax]
mov ebx, [ebx]
test ax, ax
jz is_smaller
test bx, bx
jz is_bigger
cmp ax, bx
jl is_smaller
jg is_bigger
; if the same, try next positions
pop ebx
pop eax
inc eax
inc ebx
call compare
is_smaller:
mov eax, smaller
mov ebx, smallerLen
call report
is_bigger:
mov eax, bigger
mov ebx, biggerLen
call report