Есть некоторые непонятки с видами адресов. Прошу поправить меня если я не правильно что то описал. Логический адрессегментная часть)эффективный адрес), где сегментная часть-содержание сегментного регистра. Эффективный адрес=смещение=offset:содержимое базового регистра (base) + содержимое индексного регистра (index) + смещение (displacement). Физический адрессегментная часть)*16+(эффективный адрес). И вобщем вопросы, по коду: Код (Text): .386 ASSUME CS:CODE, DS:DATA, SS:STK DATA SEGMENT USE16 DB 33d dup (?) DATA ENDS STK SEGMENT USE16 STACK DB 100h dup(?) STK ENDS CODE SEGMENT USE16 start: JMP @run STRING DB 'qwerty qwertyuiopasdf, qwert, qwe qwe' l equ 33d @run: mov AX, DATA mov DS, AX LEA ax, cs:[0044h] MOV AX, 0B800h ; адрес видеобуфера MOV ES, AX ; адрес видеобуфера в ES MOV EBX, 0 ; счетчик в 0 LEA EDI, STRING ; адрес рядка(смещение относительно чего?) MOV AH, 6 ; цвет @loop: MOV AL, CS:[EBX + edi] ; в AL символ MOV ES:[3520d + EBX*2], AX ; с AL в видеобуфер, 25 строчка MOV DS:[EBX], AL ; символ в сегмент данных MOV SS:[EBX], AL ; символ в сегмент стека INC EBX ; счетчик +1 CMP EBX, l ; сравниваем счетчик с длиной строки JB @loop ; переходим по CF=1 MOV AH, 1 INT 21h MOV AX, 4c00h INT 21h code ends END start LEA даст нам смещение относительно того сегмента в котором находится наш STRING? Как узнать логический адрес операнда ES:[3520d + EBX*2] в MOV ES:[3520d + EBX*2], AX? Каким будет логический и физический адрес JMP @run(фактически адреса метки start:? препод задавал вопрос именно про адрес метки, но метка же адреса не имеет?)? Как процессор будет вычислять эффективный адрес ES:[3520d + EBX*2] ? Какие части из "содержимое базового регистра (base) + содержимое индексного регистра (index) + смещение (displacement)" тут присутствуют? Только смещение? препод уже достал валить этими вопросами, 4 лабы как то сдал, а на 5 завалился очень надеюсь на помощь
crashtua Содержимое индексного регистра умножается на масштаб (scale factor), на 2 в приведенном коде. Только для реального режима. Т.е. да для сдачи Вашего предмета. В общем случае, нет. Какое из приведенных lea? Вообще префикс переопределения сегмента для lea не играет никакой роли (ставьте хоть cs, хоть ss, хоть...) и игнорируется. Всё, что делает lea, — это вычисляет то, что передано вторым параметром (хотя корректно говорить "вычисляет эффективный адрес второго операнда", но смысл тот же). Поэтому написать LEA ax, cs:[0044h] будет равносильно mov ax,44h, только mov ещё и на байт короче. Аналогично с lea edi, STRING (было бы, если бы было di, а не edi. С какой стати 32-разрядный регистр?). Нет смысла здесь в lea, т.к. STRING — просто число (адрес метки, точнее метка — это и есть обозванный адрес). Поэтому lea di, STRING равносильно записи mov di,offset STRING, где вместо offset STRING подставляется число, высчитываемое в процессе трансляции (в Вашем случае было бы 3), только аналогично lea на байт длиннее. С учётом того, что эта инструкция находится в цикле, где ebx постоянно растёт, логический адрес, естесственно, тоже меняется с каждой итерацией. А так естесственно подставить значения и посчитать. На первой итерации будет 0B800h:3520d+0*2 <=> 0B800h:3520 — это и есть логический адрес. Метка — это и есть адрес (хотя часто под меткой понимают содержимое по адресу). "Адрес метки start" равносильно "адрес с именем start". Адреса (ни логический, ни физический) без запуска определить невозможно, т.к. нет значения cs, определяемого DOS при загрузке образа. Будет умножать и складывать . Как было показано выше. Ну ebx используется здесь в качестве индексного регистра. Поэтому есть смещение и индексный регистр со scale factor присутствуют.
l_inc, понятно расписал Еще 1 вопросик и можно быть спокойным: MOV ES:[3520d + EBX*2], AX вычислит оно 0B800h:3520d, и соответственно у нас в сегменте кода будет что то типа (код мува)0B800h:3520d(что то там для указания на AX)? Если да, то как можно узнать логический адрес именно той записи (0B800h:3520d) в сегменте кода? (допустим значение сх=080ch)
crashtua Нет. Такого не будет. Вычисление адреса происходит во время исполнения. То, что в сегменте кода будет, определяется во время компиляции (если не рассматривать модифицируемый код). Поэтому в сегменте кода будет: префикс переопределения сегмента на указываемый es, опкод mov идентификатор регистра ebx (как индексного), множитель 2, а также значение 3520. Кроме того, будет префикс переопределения размера адреса 67h (т.к. присутствует 32-битный регистр в адресном выражении в 16-битном режиме), а также код регистра ax. Эта запись и есть логический адрес и к сегменту кода он отношения не имеет. Физический адрес можно узнать по приведенной Вами формуле: 0B800h*16 + 3520 = 0B8000h + 0DC0h = 0B8DC0h. Причём здесь значение cx, честно говоря, не понял. Видимо перепутано с cs, которое в свою очередь тоже не имеет смысла.
Miyamoto, по методичкам собственного производства. Толкового в них минимум, куски кода, короткие пояснения типа "mov пересылает туда то сюда то...".