Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Решить задачу через ассемблер

Александра Бурумбаева Ученик (114), на голосовании 4 месяца назад
Подсчитать количество символов "7" (код – 37) в диапазоне ячеек
0140..017E. Результат сохранить в ячейке 0134
Голосование за лучший ответ
GGG Просветленный (35954) 5 месяцев назад
 section .data 

section .bss

section .text
global _start

_start:
; Инициализация регистров
mov esi, 0x0140 ; Устанавливаем начальный адрес в регистр ESI
mov ecx, 0x003F ; Устанавливаем количество ячеек для проверки (0140 до 017E = 3F ячеек)
mov ebx, 0 ; Счётчик символов '7'

check_loop:
; Проверка текущей ячейки памяти
mov al, byte [esi] ; Загружаем байт по адресу ESI в регистр AL
cmp al, 0x37 ; Сравниваем его с ASCII-кодом символа '7'
jne not_seven ; Если это не '7', переходим к метке not_seven

inc ebx ; Если это '7', увеличиваем счётчик

not_seven:
inc esi ; Переходим к следующей ячейке памяти
loop check_loop ; Повторяем до тех пор, пока ECX не станет равным 0

; Сохранение результата
mov [0x0134], ebx ; Сохраняем значение счётчика в ячейку 0134

; Завершение программы
mov eax, 1 ; Системный вызов для выхода из программы
xor ebx, ebx ; Код возврата 0
int 0x80 ; Вызов ядра
Ryt Rai Ученик (147) 5 месяцев назад
section .bss
counter resb 1

section .text
global _start

_start:
; Инициализация начальных значений
mov rcx, 0x3F ; Количество ячеек для проверки (017E - 0140 + 1 = 3Fh)
mov rsi, 0x0140 ; Начальный адрес для проверки
mov rdi, counter ; Адрес счетчика

; Обнуление счетчика
mov byte [rdi], 0x00

count_loop:
; Чтение байта из текущей ячейки памяти
mov al, [rsi]

; Проверка, является ли байт символом '7' (код ASCII – 55h)
cmp al, 55h
jne not_seven

; Увеличение счетчика, если найден символ '7'
inc byte [rdi]

not_seven:
; Переход к следующей ячейке памяти
inc rsi

; Декрементирование счетчика цикла
dec rcx

; Проверка, завершен ли цикл
jnz count_loop

; Сохранение результата в ячейку 0134
mov rsi, counter
mov al, [rsi]
mov [0x0134], al

; Завершение программы
mov rax, 60 ; Системный вызов для завершения программы (sys_exit)
xor rdi, rdi ; Код завершения 0
syscall


Этот код работает для NASM x86_64
HAKER HAKER Знаток (370) 5 месяцев назад
.model small
.stack 100h

.data
start_address dw 0140h
end_address dw 017Eh
count dw 0

.code
main proc
mov ax, @data
mov ds, ax

mov bx, start_address

loop_start:
mov al, [bx]
cmp al, 37h
jne next
inc count

next:
inc bx
cmp bx, end_address
jle loop_start

mov ax, count
mov [0134h], ax

mov ah, 4ch
int 21h

main endp
end main
Объяснение кода:

Инициализация:

.model small: определяет модель памяти как маленькую, что означает использование сегмента данных и кода.
.stack 100h: резервирует 100 байт стека.
.data: определяет сегмент данных.
start_address: адрес начала диапазона ячеек.
end_address: адрес конца диапазона ячеек.
count: переменная для подсчета количества символов “7”.
.code: определяет сегмент кода.
main proc: начало процедуры main.
mov ax, @data: загружает адрес сегмента данных в регистр ax.
mov ds, ax: устанавливает сегмент данных.
Цикл обработки:

mov bx, start_address: инициализирует регистр bx начальным адресом диапазона.
loop_start: метка начала цикла.
mov al, [bx]: загружает значение из текущей ячейки в регистр al.
cmp al, 37h: сравнивает значение с кодом символа “7” (37h).
jne next: если значение не равно 37h, переходит к метке next.
inc count: если значение равно 37h, увеличивает счетчик count на 1.
next: метка для перехода после проверки значения.
inc bx: увеличивает адрес bx на 1, чтобы перейти к следующей ячейке.
cmp bx, end_address: сравнивает текущий адрес с адресом конца диапазона.
jle loop_start: если текущий адрес меньше или равен адресу конца, переходит к метке loop_start, чтобы повторить цикл.
Сохранение результата:

mov ax, count: загружает значение счетчика в регистр ax.
mov [0134h], ax: сохраняет значение счетчика в ячейку с адресом 0134h.
Завершение программы:

mov ah, 4ch: устанавливает функцию завершения программы.
int 21h: вызывает прерывание 21h для завершения программы.
Замечания:

Этот код предназначен для работы в среде DOS.
Необходимо предоставить файл с данными, в котором содержится диапазон ячеек с адресом 0140h до 017Eh.
Вы можете изменить адреса start_address, end_address и 0134h в соответствии с вашими потребностями.
Дополнительные ресурсы:

Введение в ассемблер: https://www.tutorialspoint.com/assembly_programming/assembly_programming_introduction.htm
Ассемблер для DOS: https://en.wikipedia.org/wiki/DOS_API
Victoria Просветленный (31247) 5 месяцев назад
 LDA	#$00 
TAX
TAY
:POINT1
LDA $0140, X
INX
CMP #$37
BNE POINT2
INY
:POINT2
CPX #$40
BNE POINT1
STY $0134
Похожие вопросы