В настоящее время я работаю над ускоренным курсом x86_64, в котором есть несколько очень простых примеров.Несмотря на то, что учебник называется 64-битным, они используют 32-битные регистры, я следую учебнику с 64-битными эквивалентами.Я наткнулся на следующий пример программы, которая выдает следующий вывод и объясняет, что нулевой завершающий байт отсутствует, поэтому первая операция печати строки предполагает, что вторая строковая переменная является частью первой:
ВКЛЮЧЕННЫЕ ФУНКЦИИ
; -------------------------------------------------------------------------------------------------------------------
; int slen(String message)
; String length calculation function
slen: ; this is our first function declaration
push rbx ; push the value in RBX onto the stack to preserve it while we use RBX in this function
mov rbx, rax ; move this address in RAX into RBX ( Both point to the same segment in memory)
nextchar:
cmp byte [rax], 0 ; this is the same as lesson 3
jz finished
inc rax
jmp nextchar
finished:
sub rax, rbx
pop rbx ; pop the value on the stack back into RBX
ret ; return to where the function was called
;; ---------------------------------------------------------------------------------------------------------
;; void sprint(String message)
;; String printing function
sprint:
push rdx
push rcx
push rbx
push rax
call slen
mov rdx, rax
pop rax
mov rcx, rax
mov rbx, 1
mov rax, 4
int 80h
pop rbx
pop rcx
pop rdx
;; -----------------------------------------------------------------------------------------------------------
;; void exit()
;; Exit program restore resources
quit:
mov rbx, 0
mov rax, 1
int 80h
ret
ОСНОВНАЯ ПРОГРАММА
;; Hello World Program (Externam file include)
;; Compile with: nasm -f elf64 helloworld-inc.asm
;; Link with ld helloworld-inc.o -o helloworld-inc
;; Run with ./helloworld-inc
%include 'function.asm' ; include our external file
SECTION .data
msg1 db 'Hello, brave new world!', 0Ah, 0h ;our first message string add null terminating byte
msg2 db 'This is how we recycle in NASM.', 0Ah, 0h ; our second message string add null terminating byte
SECTION .text
global _start
_start:
mov rax, msg1 ; mov the address of our first message string into RAX
call sprint ; call our string printing function
mov rax, msg2 ; move the address of our second message string into RAX
call sprint ; call our string printing function
call quit ; call our quit function
ПРЕДПОЛАГАЕМЫЙ ВЫХОД С ИХ ДАННОЙ КОМАНДОЙ
~ $ nasm -f elf helloworld-inc.asm ~ $ ld -m elf_i386 helloworld-inc.o -o helloworld-inc ~ $ ./helloworld-inc
Hello, brave new world!
This is how we recycle in NASM.
This is how we recycle in NASM.
МОЙ ВЫХОД С МОИМИ КОМАНДАМИ
nasm -f elf64 helloworld-inc.asm ld helloworld-inc.o -o helloworld-inc
Hello, brave new world!
This is how we recycle in NASM.
Мой вывод не включал ту же проблему, в которой отсутствие нулевого байта заставляло первую операцию записи использовать обе переменные и, более того, когда я тестировал следующую программу, которая просто изменяет основную программу следующим образомЯ потерял весь «Вот как мы перерабатываем в NASM».выходные данные.
SECTION .data
msg1 db 'Hello, brave new world!', 0Ah, 0h
msg2 db 'This is how we recycle in NASM.', 0Ah, 0h
Я искал ответ в Интернете и не смог найти ответ. Я попытался использовать gdb для отладки кода с помощью следующих команд:
nasm -f elf64 -g helloworld-inc.asm ld helloworld-inc.o -o hellworld-inc gdb helloworl-inc
Однако при успешном перечислении сборки выдается ошибка при попытке установить точки останова
(gdb) перерыв 17 Не удается получить доступ к памяти по адресу 0x4000ef
Итак, в заключение, пожалуйста, объясните, почему 64-битные регистры предотвращают необходимость использования нулевого байта и как я могу использовать gdb (или любой отладчик) для отладки своей сборки nasm.
Спасибо