Как-то решил я поробывать перейти с MASM на YASM. Наверное отому, что уже долго использую линукс.
Так вот, у меня возникли вопросы, на которые, я думаю, мне помогут найти ответы здесь.
yasm -f elf64 -g stabs pr.asm -o pr.o
gcc pr.o -o pr
Транслируется и линкуется нормально, но: 1. Возникает ошибка сегментации при вызывое функции puts 2. gdb не правильно отображает точки остановок в псевдоокошке свверху, где отображается код, если запустить gdb c параметром -tui
Вот код программы (она пока ничего не делает):
BITS 64
CPU Bulldozer
extern puts
global main
;;--------------------------------------------------------
;секция инициализированных переменных
SECTION .data           
    promt1: db "Starting", 0Ah, 0h     
    promt2: db "Result:", 0h
    promt3: db "Allocation error!", 0Ah, 0h
    str_funloaded: db "Loaded overlay function: ", 0h
    str_exit: db "Bye!", 0Ah, 0h
    str_calling: db "Calling overlay function...", 0Ah,  0h
    nline: db 0Ah, 0h
    o_sum: db "o_sum.bin", 0 ;путь к программе
    o_div: db "o_div.bin", 0 
    o_mul: db "o_mul.bin", 0
    o_sub: db "o_sub.bin", 0
    src_str: db "10 + 20", 0
;----------------------------------------------------------
;секция сегмент подгрузки оверлейных функций
SECTION .bss
 ostart:	resb 10
;----------------------------------------------------------
	;исполняемы код программы	 
SECTION .text
; **********************************************
;подсчет длины строки
; вход: rdx смещение строки в ds
; выход: rcx длина строки
astrlen:
    xor rcx, rcx
    push rbx
    
    mov rbx, rdx ;помещаем адрес строки в ebx
    
    strlen_start:    
    cmp byte [rbx], 0 ;сравниваем текущий символ строки с 0 символом
    je strlen_exit
    inc rbx		;увеличиваем счетчик
    inc rcx
    jmp strlen_start
    strlen_exit:
    pop rbx
    ret
; ************************************************ 
; печать строки
print:	
	push rax
	push rbx
	push rcx
	push rdx
	;подготовка к системному вызову write
	;ssize_t write(int fildes, const void *buf, size_t nbyte);
         mov rax, 4
	 ;помещаем в ebx stdout fd
	 mov rbx, 1
	 mov r8, rdx
	 call astrlen
	 mov rdx, rcx
	 ;в ecx помещаем адрес строки для печати	 
	 mov rcx, r8
	 ;вызов системного прерывания linux
	 int 80h
	 pop rdx
	 pop rcx
	 pop rbx
	 pop rax
	 ret
; ***************************************************
; загрузка оверлейной функции
run:
	mov r8, rbx
	;int open(const char *path, int oflag, ...  );
	mov rax, 5	;системмный вызов open 
	mov rcx, 0000000b
	int 80h
	;ssize_t read(int fildes, void *buf, size_t nbyte);
	mov rbx, rax
	mov rax, 3	;системный вызов read
	mov rcx, ostart
	mov rdx, 10	;размер буфера для записи оверлейной функции
	;закрыываем файл
	int 80h
	mov rax, 6
	int 80h
	;вывод сооxбщения об успешном завершении операции
	mov rdx, str_funloaded
	call print
	
	mov rdx, r8
	call print
	
	mov rdx, nline
	call print
	ret
; ***************************************************
main:
    mov rdx, promt1
    call print
    
    push  promt2
    call puts
    ; обработка параметров командной строки
    ;mob rbx, o_sum
    ;call run
    ;выход из программы 
    exit:
	mov rdx, str_exit
	call print
	mov rax, 1
	mov rbx, 0
	int 80h
    error:
	;print promt3
Ошибка сегментации, когда функция put вызывает функцию strrlen: Вот backtrace:
                            Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7abc3a1 in __strlen_sse2 () from /lib/libc.so.6
(gdb) bt
#0  0x00007ffff7abc3a1 in __strlen_sse2 () from /lib/libc.so.6
#1  0x00007ffff7aa56ec in puts () from /lib/libc.so.6
#2  0x000000000040058a in main () at lab4_x64.asm:112
Еще такой вопрос к знатокам дела: В 64 битных процессорах отказались от сегментных регистров? Или как? Потому что, yasm при трансляции сообщил, что сегментные регистры игнорируются. Я понимаю, что в 32 битных их оставили для совместимости. Или я не так понял что-то?