Проблема доступа к переменной сборки на основе прерываний x86 - PullRequest
0 голосов
/ 11 ноября 2010

У меня есть (на первый взгляд) простой вопрос для чтения в строке и его распечатки снова с использованием сборки на основе прерываний x86.Проблема у меня есть доступ к строке, которая была прочитана правильно.Переменная - input db 20, 0, " " - моя начальная строка.После того, как я вызову входное прерывание, 0 теперь должен содержать длину строки, которую мне нужно сохранить и передать в cx, когда я вызываю прерывание печати.20 - максимальная длина ввода.Я сталкиваюсь с двумя проблемами - как получить доступ к длине строки (я использую произвольное число, которое либо сокращает его, либо печатает мусор после конца), и как получить доступ к строке без битового числа вНачните?Любая помощь приветствуется, моя попытка:

(я использую tasm & Tlink под win 7 32 bit, а также под эмуляцией dos box)

;7. Read in a String of characters and Print the string back out.


.model small
.stack 100h
.data


    colour db 00001111b
    input db 20, 0, "                    "
    strlen dw 20; this should be ?


.code

main:

    call initsegs
    call readstring
    call printstring
    call exit



PROC printstring 

    push ax bx cx dx bp

    mov ah, 13h ; int 13h of 10h, print a string
    mov al, 1 ; write mode: colour on bl    
    mov bh, 0 ; video page zero
    mov bl, colour; colour attribute
    mov cx, strlen; getting this is the problem
    mov dh, 10; row
    mov dl, 10; column
    mov bp, offset input ; es:bp needs to point at string..this points to string but includes its max and length at the start

    int 10h;


    pop bp dx cx bx ax 

    ret

ENDP printstring






PROC readstring 

    push ax dx


    mov ah, 0ah ; function a of 21h - read a string
    mov dx, offset input ; reads string into DS:DX so DX needs be offset of string variable

    int 21h ; call the interrupt
    ;mov strlen ....something
    pop dx ax

    ret

ENDP readstring



PROC exit

    mov ah, 4ch
    INT 21h

    RET

ENDP Exit


PROC initsegs

    push ax

    mov ax, @DATA
    mov ds, ax
    mov es, ax

    pop ax

    RET

ENDP initsegs



end main

Ответы [ 2 ]

0 голосов
/ 12 ноября 2010

То, что у вас здесь, известно как Pascal String.В исходной версии (используемой в 16-битном языке Паскаль) для хранения длины строки использовался первый байт, а остальные байты содержали фактическую строку (не завершенную нулем).Это дает максимальную длину в 255 байт.

В версии используется 32-битная версия Delphi, использующая слегка другой подход:

struct {
  DWORD allocated_size;
  DWORD used_size;
  char* buff;
};

Это похоже на ваш случай, но вы используете размер BYTE вместо DWORD.Стандартный способ работы с ними - сохранить указатель на фактическую символьную строку и использовать отрицательные смещения для специальных полей, например:

lea ax, [input + 2]  //; standard string, could need a trailing '\0'
mov al, BYTE PTR [input+2 - 1] //; strlen
mov al, BYTE PTR [input+2 - 2] //; allocated buff size
0 голосов
/ 11 ноября 2010
inputBuffer LABEL BYTE 
maxChar     BYTE 10 
numinput    BYTE ? 
buffer      BYTE 10 DUP (0) 
... 
     mov  ah, 0Ah  ; string input 
     mov  dx, OFFSET inputBuffer 
     int  21h

Поместите ваш inputBuffer в раздел .data, он работает как структура, которая используется прерыванием 21 (заполняет numinput числом символов read0

...