Современные технологии автоматизации» («СТА») —  журнал для квалифицированных специалистов по промышленной автоматизации Форум СТА — современные технологии автоматизации Домашняя страница
Домашняя страница форума CTA Домашняя страница форума CTA > II. АСУТП и SCADA > Программное обеспечение
  Активные темы Активные темы
  FAQ FAQ  Искать в форуме   Зарегистрироваться Зарегистрироваться  Вход в систему Вход в систему

Передача данных с Ассемблера в UL

 Ответить Ответить Страница  <123>
Автор
Сообщение
sanwork Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 08 Март 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 440
Свойства публикации Свойства публикации   Ответить, цитируя автора - sanwork Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Тема сообщения: Передача данных с Ассемблера в UL
    Опубликовано: 08 Март 2007 02:14

Немного добавлю.

Чуть-чуть исправлюсь

_DATA  SEGMENT  WORD  PUBLIC  'DATA'  USE16

Насчет множества сегментов данных - это для одного модуля.

Все сказанное относится и к сегменту кода :

_TEXT  SEGMENT  BYTE  PUBLIC  'CODE'  USE16
            ASSUME  CS:_TEXT
            ASSUME  DS:_DATA

Если указан класс сегмента  'КЛАСС' , то линковщик в первую очередь располагает сегменты одного класса рядом, друг за другом. Если класс отсутствует, то сегменты с одинаковым именем  _ИМЯ об'единяются в один сегмент.

Ну а можно и вообще переписать ассемблерный код с упрощенными директивами сегментации, и об'явить 'большую' модель памяти LARGE, чтобы сформировать дальние адреса :

    .MODEL  LARGE

    .DATA                     ; Сегмент данных
    ; ...
    ; ...
    ; ...                          ; ENDS - не нужно

    .CODE                    ; Сегмент кода
    .386
    ; ...
    ; ...
    ; ...                          ; ENDS - не нужно

Упрощенные директивы возможно использовать потому, что как видно в исходнике на UL - применены стандартные для 16-ти разрядных DOS-программ имена сегментов. Ну если не прокатит - значит использовать стандартное об'явление сегментов.

С переходом на 32-х разрядную среду надобность во всех этих сегментах отпадет - там одна плоская модель памяти FLAT.

С уважением, SAN.

 

Наверх
Vel_ Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 25 Апрель 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 116
Свойства публикации Свойства публикации   Ответить, цитируя автора - Vel_ Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 09 Март 2007 05:59

Интересно, а Вы с программами UL разбирались? Откуда такие измышления:

    .CODE                    ; Сегмент кода
    .386

Где Вы видели программы для контроллеров, программируемых с помощью UL (16, 32) для процессоров 386. Если все программы пишутся для .86, .186? В ADAM 5510 188 процессор.

<С переходом на 32-х разрядную среду надобность во всех этих сегментах отпадет - там одна плоская модель памяти FLAT.>

Какая может быть модель памяти FLAT в 16 разрядной среде исполнения?

Почитайте для начала раздел справки "Системные соглашения UltraLogik" из файла помощи UL.

Привожу пример минимальной программы для ADAM 5510 на чистом ASM. Единственно, я использовал библиотеку собственного написания ADAM5510.LIb в которой реализован протокол обмена PlcNet (взамен стандартной из 80x86.LIB)

; =======================================

DGROUP  group CONST,VARLIST,DATA,STORED

; ======================================
  includelib 80x86.LIB
  includelib ADAM5510.LIb
; ===================================

  extrn $_InitDivErr:near ;
  extrn $_InitTimer5510:near ;
  extrn $_InitRS5510_1:near ; $_$_InitRS5510_1:near
  extrn $_InitRS5510_2:near ; $_InitRS5510_2:near
  extrn $_DoneRS5510_1:near ; $_$_DoneRS5510_1:near
  extrn $_DoneRS5510_2:near ; $_DoneRS5510_2:near
  extrn $_DoneTimer5510:near ;
  extrn $_DoneDivErr:near ;
;--------------------------------------------------------+++
    extrn STimer_enable:near ; Активация сторожевого таймера (near)
    extrn STimer_disable:near ; Отключение сторожевого таймера (near)
    extrn STimer_clear:near   ; Сброс сторожевого таймера (near)
;--------------------------------------------------------+++

; ==============================

SYSTEM  segment byte public 'CODE' use16
  assume ds:DGROUP, cs:SYSTEM

  public P1_PROG
P1_PROG  proc near  ; CODE XREF: $_Cycle+7p
  mov al, VX1_VAR
  mov VIX1_VAR, al
  mov al, VX2_VAR
  mov VIX2_VAR, al
  mov al, VX3_VAR
  mov VIX3_VAR, al
  retn
P1_PROG  endp


  public $_StartUp
$_StartUp proc near
  call $_InitDivErr ; $_InitDivErr
  call STimer_enable ; Активация сторожевого таймера (near)
  call $_InitTimer5510
  mov dx, 138h       ; Записываем в dx адресс DIP-пеключателя (138h)
  in al, dx         ; Считываем бит код сетевого адреса из порта (138h)
  mov $_NetNode, al    ; Записываем в $_NetNode бит код сетевого адреса
  mov bx, 7
  call $_InitRS5510_1 ; $_$_InitRS5510_1
  mov bx, 7
  call $_InitRS5510_2 ; $_InitRS5510_2
  retn
$_StartUp endp


  public $_Cycle
$_Cycle  proc near
  cmp P1_STATUS, 0      ; Сравнение (статус программы P1) = 0 (отключена)
  jz STATUS_P1_0       ; если ноль, то переход на метку STATUS_P1_0
  call P1_PROG         ; запуск программы P1

STATUS_P1_0:        
    call STimer_clear     ; Сброс сторожевого таймера (near)
  retn
$_Cycle  endp


  public $_DoneProg
$_DoneProg proc near
  call $_DoneRS5510_1 ; $_$_DoneRS5510_1
  call $_DoneRS5510_2 ; $_DoneRS5510_2
  call $_DoneTimer5510

    call STimer_disable ; Отключение сторожевого таймера (near)
 
  call $_DoneDivErr ; $_DoneDivErr
  retn
$_DoneProg endp

SYSTEM  ends

; ==========================================

CONST  segment byte public 'DATA' use16
  assume ds:DGROUP         ;, cs:CONST
 
  public $_ProjectName
$_ProjectName db ' Masm 6.11 - K22_M.asm "Nazarov V.D."$' ; Название проекта

  public $_CompileTime
$_CompileTime db 'Meu4'     ;

  public $_NetNode
$_NetNode db 1   ; Сетевой адресс с DIP-переключателя

CONST  ends

; =====================================

; Segment type: Pure data
VARLIST  segment byte public 'DATA' use16
  assume ds:DGROUP          ;, cs:VARLIST
  ;org 20h

  public ERR_SEG_NAME
ERR_SEG_NAME db 7,'ERR_SEG' ;

  public INTEGER_TYPE
INTEGER_TYPE db 7,'INTEGER' ; 

  public ERR_OFS_NAME
ERR_OFS_NAME db 7,'ERR_OFS' ; 

  public VX1_NAME
VX1_NAME db 3,'Vx1'         ; 

  public BOOLEAN_TYPE
BOOLEAN_TYPE db 7,'BOOLEAN' ; 

  public UP_NAME
UP_NAME  db 2,'Up'           ; 

  public VIX1_NAME
VIX1_NAME db 4,'Vix1'         ; 

  public VX2_NAME
VX2_NAME db 3,'Vx2'         ; 

  public VIX2_NAME
VIX2_NAME db 4,'Vix2'         ; 

  public VIX3_NAME
VIX3_NAME db 4,'Vix3'         ; 

  public VX3_NAME
VX3_NAME db 3,'Vx3'         ; 

  public $_CntNetworkVar
$_CntNetworkVar db    9 ; 
  db    0 ; 
  public $_LstNetworkVar
$_LstNetworkVar dw offset ERR_SEG_NAME
  dw offset ERR_SEG_VAR
  dw offset INTEGER_TYPE
  db    1 ; 
  db    7 ; 
  dw offset ERR_OFS_NAME
  dw offset ERR_OFS_VAR
  dw offset INTEGER_TYPE
  db    1 ; 
  db    7 ; 
  dw offset VX1_NAME
  dw offset VX1_VAR
  dw offset BOOLEAN_TYPE
  db    0 ; 
  db    3 ; 
  dw offset UP_NAME
  dw offset UP_VAR
  dw offset BOOLEAN_TYPE
  db    0 ; 
  db    2 ; 
  dw offset VIX1_NAME
  dw offset VIX1_VAR
  dw offset BOOLEAN_TYPE
  db    0 ; 
  db    4 ; 
  dw offset VX2_NAME
  dw offset VX2_VAR
  dw offset BOOLEAN_TYPE
  db    0 ; 
  db    3 ; 
  dw offset VIX2_NAME
  dw offset VIX2_VAR
  dw offset BOOLEAN_TYPE
  db    0 ; 
  db    4 ; 
  dw offset VIX3_NAME
  dw offset VIX3_VAR
  dw offset BOOLEAN_TYPE
  db    0 ; 
  db    4 ; 
  dw offset VX3_NAME
  dw offset VX3_VAR
  dw offset BOOLEAN_TYPE
  db    0 ; 
  db    3 ; 
VARLIST  ends

; ====================================

; Сегмент 'DATA'
DATA  segment byte public 'DATA' use16
  assume ds:DGROUP        ;, cs:_DATA
  ;org 0B0h

  public ERR_SEG_VAR
ERR_SEG_VAR dw    0 ;  ; DATA XREF: VARLIST:0062o
 
  public ERR_OFS_VAR
ERR_OFS_VAR dw    0 ;  ; DATA XREF: VARLIST:006Ao
 
  public VX1_VAR
VX1_VAR  db 1   ; DATA XREF: P1_PROGr VARLIST:0072o
  public UP_VAR
UP_VAR  db    1 ;  ; DATA XREF: VARLIST:007Ao
  public VIX1_VAR
VIX1_VAR db 0   ; DATA XREF: P1_PROG+3w VARLIST:0082o
  public VX2_VAR
VX2_VAR  db 1   ; DATA XREF: P1_PROG+6r VARLIST:008Ao
  public VIX2_VAR
VIX2_VAR db 0   ; DATA XREF: P1_PROG+9w VARLIST:0092o
  public VIX3_VAR
VIX3_VAR db 0   ; DATA XREF: P1_PROG+Fw VARLIST:009Ao
  public VX3_VAR
VX3_VAR  db 1   ; DATA XREF: P1_PROG+Cr VARLIST:00A2o
  public P1_STATUS
P1_STATUS db 1   ; DATA XREF: $_Cycler
DATA  ends

; ==============================

; Сегмент "Сохраняемые переменные"
STORED  segment byte public 'DATA' use16
  public StoredEnd
StoredEnd label byte
STORED  ends

; ==========================

; Сегмент "Стек"
STACK  segment para stack 'STACK' use16
  assume ds:DGROUP        ;, cs:STACK
  db 1000h dup(?) ;
STACK  ends

  end

Такую же программу и генерирует UL 16.

Vel
Наверх
sanwork Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 08 Март 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 440
Свойства публикации Свойства публикации   Ответить, цитируя автора - sanwork Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 09 Март 2007 14:39

Понятно. В любом случае надо внимательно следить чтобы имена переменных и функций, тип доступа - NEAR или FAR, а так-же принадлежность к сегментам или группе - совпадали в разных модулях, чтобы при сборке (линковке) все срослось между собой. Одна из основных причин неработоспособности может быть в этом.

С уважением, SAN.

 

Наверх
RomanS Смотреть выпадающим
Новичок
Новичок
Аватар

Присоединился: 05 Март 2007
Категория: Kazakhstan
Online Status: Offline
Публикации: 14
Свойства публикации Свойства публикации   Ответить, цитируя автора - RomanS Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 11 Март 2007 12:52
Первоначально опубликовано Vel_

Статус = Start  ( Auto Run ) ; если не будете запускать по call

Потом на появившейся вкладке указывате путь к скомпановому .obj и в поле Public Name выбираете нужную Вам функцию из .obj.

Всё!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Дело сдвинулось с мертвой точки..., только вместо статуса start, ставлю Stop (программа вызывается другой программой). В поле Public Name видно только имя процедуры, которая объявлена как Public (остальных, которые объявлены как EXTRN, не видно, так и должно быть?). Проэкт получился, но переменая, extrn DECSH1_VAR:far, своего значения не меняет.(Смотрю через PLCNET OPC Server). Проверю текст программы на АССАМе. Может там ошибка...

Всё знать не возможно, но обовсем можно иметь понятие.
Наверх
Vel_ Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 25 Апрель 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 116
Свойства публикации Свойства публикации   Ответить, цитируя автора - Vel_ Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 12 Март 2007 05:22

<В поле Public Name видно только имя процедуры, которая объявлена как Public (остальных, которые объявлены как EXTRN, не видно, так и должно быть?)>

Да, не Public процедуры и функции не видны в поле Public Name, Вы ведь вызываете какието основные функции (Public), а остальные (EXTRN) использует ваша процедура.

При записи в переменную, у Вас должен быть обязательно установлен регистр ds на DGROUP. Здесь нюанс, если вы напрямую его установите: mov ds, seg DGROUP, то ничего не получится (для присоеденяемого obj). Поэтому в Вашем модуле необходимо в сегменте SYSTEM (перед кодом) объявить:

SYSTEM  segment byte public 'CODE' use16
  assume ds:DGROUP, cs:SYSTEM
  
Seg_DGROUP    dw seg DGROUP ;обявление переменной

А затем установить регист ds на DGROUP перед записью (считыванием) переменной:

mov     ds, word ptr cs:Seg_DGROUP ; устанавливаем ds:DGROUP

И не забывайте, что ваша переменная (DECSH1) должна быть объявлена в UL, в таблице переменных, как глобальная (+ сетевая и т.д.). Это поместит переменную в сегмент DATA и Вы получите к ней доступ (см. пример программы выше).

Vel
Наверх
RomanS Смотреть выпадающим
Новичок
Новичок
Аватар

Присоединился: 05 Март 2007
Категория: Kazakhstan
Online Status: Offline
Публикации: 14
Свойства публикации Свойства публикации   Ответить, цитируя автора - RomanS Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 12 Март 2007 14:12

Учитывая весь выше изложеный материал, была написана програмка для получения данных с Ассе-ра в UL. Для проверки работоспособности програмки (зависает ли она или нет) в UL я создал простенькую програмку-счетчик. При каждом выполнение ( проходе) UL-пороги переменная (допустим Cо1) увеличивает своё значение на 1, дойдя до 100 сбрасывается в 1 и увеличивается занова. После каждого увеличения переменной запускается програмка для получение данных из Ассе-ра. Компилирую, запускаю, смотрю..., а результат 0. Т.е. переменая (DECSH1), которая должна получить данные из Асма, равна 0, а Со1 своё значение меняет исправно ( но быстро,хотя не в этом суть). Я урезал программку, оставив самое нужно ( отбросив работу с шифраторами) - результат тот же. Вот эта программка:

DGROUP group _DATA, _BSS
extrn DECSH1_VAR:far
SYSTEM segment byte public 'CODE' use16
Assume CS:SYSTEM, DS:DGROUP
Seg_DGROUP dw seg DGROUP
public SHIF
SHIF proc near
push ds
push dx
push ax
push es
push si
mov ds,word ptr cs:Seg_DGROUP
assume ds:nothing
mov al,012h
mov byte ptr ds:DECSH1_var,al
mov byte ptr ds:DECSH1_var+1,al  ;Revolution
mov byte ptr ds:DECSH1_var+2,al  ;Step Ecodera
mov byte ptr ds:DECSH1_var+3,al
pop si
pop es
pop ax
pop dx
pop ds
retn
SHIF endp
SYSTEM ends
_DATA segment word public 'DATA' use16
_DATA ends
_BSS segment word public 'BSS' use16
_BSS ends
 end

Что не так? И зачем сегменты _DATA и _BSS (они же вроде бы не используются?). Что это за сегмент nothing в строке assume ds:nothing?

  

Всё знать не возможно, но обовсем можно иметь понятие.
Наверх
sanwork Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 08 Март 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 440
Свойства публикации Свойства публикации   Ответить, цитируя автора - sanwork Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 13 Март 2007 00:25

Тут вот какое дело.
В каждом сегменте кода, вначале должны быть настроены нужные сегментные регистры, которые будут использоваться в пределах этого участка кода, по крайней мере - сегмент данных DS. Проще говоря - в DS надо загрузить адрес нужного сегмента, например данных.
DGROUP - это не сегмент, а некая директива наделяющая сегменты определенными свойствами. Например к сегментам включенным в группу можно применить ключ SEG, дающий адрес сегмента.
DGROUP не используется в операциях взятия адреса, хотя формально он будет указывает на сегмент, об'явленный в перечислении последним. Например :

gruppa  GROUP  _SEG1, SEG2, BUBU, _KUKU

Здесь в операции    SEG  gruppa    будет получен адрес сегмента  _KUKU. Ну так конечно не делается, что если нужен адрес сегмента   BUBU ?

Директива  ASSUME  - еще одно средство работы с сегментами, и используется совместно с  SEG,  SEGMENT,  NOTHING, GROUP. Сама  ASSUME  прямо ничего не делает, а указывает компилятору, так сказать, границы дозволенного, сообщая что в текущем сегменте тот или иной регистр будет связан с определенным сегментом. Вставляя её в определенном месте кода, можно сделать чтобы компилятор позволил то или иное обращение к области памяти через сегментные регистры, или же наоборот ужесточил контроль над доступом.
Действие ключа  NOTHING  зависит от того что было до этого. Установка  ASSUME DS: NOTING  в общем случае снимает всякий контроль над доступом, усыпляет бдительность компилятора, отменяет все предыдущие настройки, и позволяет далее по коду присваивать регистру любое значение. В последствии контроль можно вернуть :  ASSUME DS:BUBU.

Но об'явления ничего не делают, и в регистр надо явно загрузить сегмент.
В Вашем коде пожалуй следует изменить запись
...
Seg_DGROUP dw seg DGROUP
...
присвоив переменной  Seg_DGROUP  значение конкретного сегмента данных, именно в котором находится переменная  DECSH1_VAR
...
Seg_DGROUP dw seg СЕГМЕНТ_ДАННЫХ_С_ПЕРЕМЕННОЙ_DECSH1_VAR
...

И тогда инструкция
...
mov ds,word ptr cs:Seg_DGROUP
...
загрузит в  DS  нужный адрес.
Распространен и более изящный прием
...
push SEG СЕГМЕНТ_ДАННЫХ_
pop  ds
...

Можно применить и другие способы, сохраняя общий смысл.

Разумеется, настройка регистра  DS  должна быть сделана и в  UL !
Переменная  DECSH1_VAR  об'явленная в модуле  UL, обязательно должна принадлежать какому-нибудь сегменту, иначе её никто не увидит.
Почему бы не использовать уже имеющиеся сегменты  _DATA  и _BSS ? Эти сегмнты - скорее всего дань стандарту. Наверное,  UltraLogic  рассчитан  на компоновку с модулями написанными на языках высокого уровня, где принята стандартное соглашение по об'явлению и размещению DOS-овских сегментов  и групп  - DOSSEG. При "ручном" написании программ сегменты можно назначать какие угодно, с обеих сторон.

Я пробовал исполнить Ваш код, практически в неизменном виде. Вместо  UL, был имитирован некий головной модуль вызывающий процедуру  SHIF. Сперва не сходилось, но после описанных изменений - заработало.

С уважением, SAN.

Наверх
Vel_ Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 25 Апрель 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 116
Свойства публикации Свойства публикации   Ответить, цитируя автора - Vel_ Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 13 Март 2007 05:53

Я не согласен с <sanwork>

Адресс переменной в памяти приложения (20 бит) вычисляется на основании ds + offset <Переменная>.

Поэтому ds должен указывать на начало сегмента данных (у нас это группа VARLIST,DATA,STORED) и тогда ds:DECSH1_var (ds + "смещение DECSH1_var в сегменте данных") укажет на адресс переменной в памяти!

Уберите инструкцию assume ds:nothing после установки ds на сегмент данных (слово «NOTHING», означает отмену действия предыдущей assume для данного регистра).

Если Вы не используете obj написанные на СИ, то используйте опцию "80x86 processors family compiler" в UL и тогда сегмент будет DATA (а не _DATA) и не надо объявлять _BSS (он для совместимости с СИ obj)

Тогда получится:

DGROUP  group VARLIST,DATA,STORED
extrn DECSH1_VAR:far
SYSTEM segment byte public 'CODE' use16
Assume CS:SYSTEM, DS:DGROUP
Seg_DGROUP dw seg DGROUP
public SHIF
SHIF proc near
push ds
push dx
push es
push si
mov ds,word ptr cs:Seg_DGROUP
mov al,012h
mov byte ptr ds:DECSH1_VAR,al
mov byte ptr ds:DECSH1_VAR+1,al  ;Revolution
mov byte ptr ds:DECSH1_VAR+2,al  ;Step Ecodera
mov byte ptr ds:DECSH1_VAR+3,al
pop si
pop es
pop dx
pop ds
retn
SHIF endp
SYSTEM ends

VARLIST  segment byte public 'DATA' use16
  assume ds:DGROUP
VARLIST  ends

DATA  segment byte public 'DATA' use16
  assume ds:DGROUP
DATA  ends

STORED  segment byte public 'DATA' use16
  assume ds:DGROUP
STORED  ends 

end

 

Пример модуля для UL:

http://forum.cta.ru/forum_posts.asp?TID=1743&PN=2

Vel
Наверх
sanwork Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 08 Март 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 440
Свойства публикации Свойства публикации   Ответить, цитируя автора - sanwork Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 13 Март 2007 12:45

Попробуем c реальным  UL  модулем, который Вы выложили.

ASSUME DS:DGROUP - разрешает далее по коду загружать в  DS  адреса входящие в группу  DGROUP, и особо ни к чему не обязывает. Может как-то случайно совпали адреса сегмнта данных и значение полученное  SEG DGROUP  ?  А кстати, в каком же сегменте находится  DECSH1_VAR ?

Комбинации с сегментами - дело довольно сложное и тонкое, особенно при смешанных операциях с 16-ти и 32-х разрадными операндами. Хотелось бы прояснить этот вопрос на будущее.

С уважением, SAN.

 

Наверх
Vel_ Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 25 Апрель 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 116
Свойства публикации Свойства публикации   Ответить, цитируя автора - Vel_ Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 13 Март 2007 13:17

DECSH1_VAR находится в сегменте DATA

(как и все глобальные переменные, посмотрите пример минимальной программы для ADAM 5510 на чистом ASM, выше в этом разделе)

В VARLIST находятся имена сетевых переменных и их таблица смещений.

В STORED находятся переменные с атрибутом "сохраняемые".

И еще, реакция на ASSUME у TASM и MASM несколько различается, примеры obj написаны под TASM.

Vel
Наверх
 Ответить Ответить Страница  <123>

Переход на форум Права доступа на форуме Смотреть выпадающим

Bulletin Board Software by Web Wiz Forums® version 9.64
Powered by Web Wiz Forums Free Express Edition
Copyright ©2001-2009 Web Wiz