str2 db ?
не пустая строка. db
означает "определить байт", а ?
означает один неинициализированный байт.
db "0neWord"
удобен для ассемблера, он скомпилируется в серию байтов, определенных как '0', 'n', 'e', ..., 'd'
. В ассемблере нет такого понятия, как "строковый" тип, все скомпилировано в машинный код, который можно рассматривать как последовательность байтов. Какой «тип» данных хранится в памяти, зависит от инструкций, используемых для доступа к ним, но в памяти все представляет собой просто серию байтов и может рассматриваться как таковая.
Возможно, вам пора проверить документацию по отладчику emu8086 и посмотреть память по адресу str1
после загрузки кода в отладчик, чтобы увидеть, как он скомпилировался.
Поэтому, как только вы скопируете второй байт из str1
в str2
, вы начнете перезаписывать часть памяти, которую вы не ожидали перезаписать.
Чтобы выделить некоторый буфер памяти фиксированного размера, вы можете использовать, например, str2 db 100 DUP(?)
, выполнив 100 раз ?
определение для db
, тем самым зарезервировав там 100 байтов памяти, следующие байты машинного кода в том же разделе будут скомпилированы за пределами адреса str2+100
.
Чтобы что-то сделать с str1
"строкой", вам нужно знать:
1) его адрес в памяти, у ассемблера x86 есть много способов получить его, но два самых простых:
mov <r16>,OFFSET str1
(r16 — любой регистр 16b)
lea <r16>,[str1]
(в данном случае делает то же самое)
2) его размер ИЛИ структура. Вы не поместили туда никакой структуры, например, строки с завершающим нулем имеют байт со значением 0
в конце, или служба DOS int 21h, ah=9
для отображения строки ожидает строку, заканчивающуюся знаком доллара '$'
и т. д. Таким образом, вам нужен как минимум размер. И директиву ассемблера EQU
, и "текущую позицию" можно использовать для вычисления размера str1
следующим образом:
str1 db "0neWord"
str1size EQU $-str1 ; "$" is assemblers "current_address" counter
Хм, сначала я попытался проверить это, прочитав некоторые документы, но мне очень трудно найти хорошую полную документацию по emu8086 (нашел что-то вроде "справки", и в ней полностью отсутствует описание директив ассемблера).
Интересно, почему так много людей все еще останавливаются на этом, а не на linux + nasm/подобном, которые полностью бесплатны, с открытым исходным кодом и задокументированы.
Итак, будем надеяться, что emu8086 работает как MASM/TASM, и что я все еще правильно помню этот синтаксис, тогда указанное выше определение размера должно работать. В противном случае обратитесь к своим примерам/документам.
Наконец, когда у вас есть адрес, размер и достаточно большой целевой буфер (опять же, чтобы загрузить его адрес, вы можете использовать OFFSET
или lea
в emu8086), вы можете закодировать свою задачу, например, таким образом:
; pseudo code follows, replace it by actual x86 instructions
; and registers as you wish
; ("r16_something" means one of 16b register, r8 is 8b register)
lea r16_str1,[str1] ; load CPU with address of str1
mov r16_counter,str1size ; load CPU with str1 size value
lea r16_str2,[str2] ; load address of target buffer
loop_per_character:
mov r8_char,[r16_str1] ; read single character
cmp r8_char,'0'
jne skip_non_ascii_zero_char
; the character is equal to ASCII '0' character (value 48)
mov r8_char,'O' ; replace it with 'O'
skip_non_ascii_zero_char:
; here the character was modified as needed, write it to str2 buffer
mov [r16_str2],r8_char
; make both str1/2 pointers to point to next character
inc r16_str1
inc r16_str2
; count down the counter, and loop until zero is reached
dec r16_counter
jnz loop_per_character
; the memory starting at "str2" should now contain
; modified copy of "str1"
; ... add exit instructions ...
Хм.. оказывается, "псевдокод" - это полный код x86, вам просто нужно назначить реальные регистры псевдо-и заменить их везде в исходнике.
Я постарался разместить там очень обширные комментарии (с моей точки зрения), чтобы можно было понять каждую используемую инструкцию. Вы должны проконсультироваться с каждым из справочного руководства по инструкциям Intel, перечитывая его с любым учебным пособием / уроками, которые у вас есть для сборки, пока вы не почувствуете, что понимаете, что такое регистр, память и т. д.
Также отлаживайте код по инструкции, проверяя состояние ЦП (значения регистров, флаги) и содержимое памяти после каждой инструкции, чтобы понять, как это работает.
person
Ped7g
schedule
14.11.2016