Добавление двух строк в сборке

#linux #assembly #nasm #intel

#linux #сборка #nasm #intel

Вопрос:

Мы изучили только прикосновение (под прикосновением я ничего не имею в виду в классе, только теоретические разговоры о том, как работают регистры) сборки в школе, и мой профессор хочет, чтобы мы сделали что-то в сборке немного сложнее, чем сложение двух целых чисел. Я провел кучу исследований и придумал некоторый код. Я использую Microsoft Visual Code на виртуальной машине Linux. Насколько я понимаю, код помещается input1 в ECX, затем помещается input2 в ECX, затем это по существу добавляется, если длина input1 составляет не менее 10 байт. Не совсем уверен, как это работает. Если я использую менее 10 байт для первого ввода, я получаю следующий ввод, напечатанный в новой строке.

Я пытался понять, как [переменная] и переменная, значение в зависимости от адреса, если я правильно понимаю, вписываются в это, и поиграл с зарезервированными байтовыми переменными. Я не прошу, чтобы мой проект был завершен, но я чувствую, что я слепо пытаюсь это сделать, в отличие от without direction. Заранее спасибо, ребята!

section .text

 global main        ;must be declared for using gcc
extern printf      ;C library used to print
extern exit        ;C library used to exit
extern scanf       ;C library used to input user entry
  

main: ;tell linker entry point, called main due to C library usage

 ;Reads prompt message          
mov eax, 4         ;system call number (sys_write)
mov ebx, 1         ;file descriptor (stdout)
mov ecx, prompt1   ;message to write called prompt
mov edx, len1      ;message length
int 0x80           ;call kernel

;Accept user input
mov eax, 3         ;system call number (sys_read)
mov ebx, 0         ;file descriptor (stdin)
mov ecx, input1    ;variable to read into, i.e. input
mov edx, 25        ;input length
int 0x80           ;call kernel


;Reads prompt message          
mov eax, 4         ;system call number (sys_write)
mov ebx, 1         ;file descriptor (stdout)
mov ecx, prompt2   ;message to write called prompt
mov edx, len2      ;message length
int 0x80           ;call kernel

;Accept user input
mov eax, 3         ;system call number (sys_read)
mov ebx, 0         ;file descriptor (stdin)
mov ecx, input2    ;variable to read into, i.e. input
mov edx, 25        ;input length
int 0x80           ;call kernel


 ;cld
mov al, 0
mov ecx, 50
mov edi, input3
repne scasb
dec edi
mov ecx, 2
mov esi, input4
rep movsb
int 0x80

;Display user input
mov eax, 4         ;system call number (sys_write)
mov ebx, 1         ;file descriptor (stdout)
mov ecx, input1    ;message to write
mov edx, 50        ;message length
int 0x80           ;call kernel



call exit   
  

section .data

 prompt1 db  'Please enter your first string: ', 0xa  ;string to print for user input
len1    equ $ - prompt1                              ;length of string prompt 

prompt2 db  'Please enter your second string: ',0xa  ;string to print for user input
len2    equ $ - prompt2                              ;length of string prompt        

input3: times 10 db  0                               ;variable input is of 10 bytes, null string terminated
input4: times 1  db  0
  

section .bss

 input1 resb 50
input2 resb 25
  

Комментарии:

1. Что ж, это кажется странным подходом. Я бы подумал, что вы хотели бы поместить адрес завершающегося нулем символа (конец строки 1) в EDI и начало строки 2 в ESI , а затем movsb пока ESI значение не станет равным нулю. (вам нужно убедиться, что памяти, зарезервированной для строки 1, достаточно для хранения string 1 string 2 ) По сути, вы просто копируете строку 2 в конец строки 1.

2. Также будьте осторожны "I am using Microsoft Visual Code on a Linux VM" — если эта виртуальная машина является WSL, то сборка не выполняется (в основном не выполняется), потому что WSL не является полноценной виртуальной машиной.

3. @DavidC.Rankin Я ценю ответ, Дэвид, как я уже сказал, мы даже не рассматривали код на ассемблере, только регистры и основы hello world. Итак, у меня просто очень ограниченные знания, я попробую то, что вы упомянули, и отчитаюсь. Также я использую Oracle VM VirtualBox.

4. @DavidC.Rankin Еще один вопрос к вам, буду ли я использовать SCASB для поиска завершающего символа null в строке? Я сделал это, а затем скопировал input2 в input1 с нулевой строкой, учитывая длину строки, но она по-прежнему не взаимодействует. Вы бы пошли по этому маршруту?

5. Да, вы можете использовать scansb для сканирования до конца строки 1, чтобы адрес был в EDI, затем movsb для добавления всех байтов из строки 2 в ESI. Добавьте в закладки ссылку на инструкции для x86 и amd64 и используйте ее каждый раз, когда используете системный вызов. (отличная ссылка)