1. Если вы только начинаете программировать на ассемблере и не знаете с чего начать, тогда попробуйте среду разработки ASM Visual IDE
    (c) на правах рекламы
    Скрыть объявление

Цикл со строкой

Тема в разделе "WASM.ASSEMBLER", создана пользователем Serjuk, 12 мар 2011.

  1. Serjuk

    Serjuk New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2011
    Сообщения:
    17
    Здравствуйте, задание вводится с клавиатуры строка и позиция в строке, с которой надо отрезать строку :

    Код (Text):
    1. INCLUDE Irvine32.inc
    2. BUFMAX = 128 ; максимальный размер буфера
    3. .data
    4. buffer BYTE BUFMAX DUP(0)
    5.  number BYTE ?
    6. .code
    7. main PROC    
    8. call ClrScr                           ;очистить экран
    9.  
    10. mov edx,OFFSET buffer                  ;загрузим адрес буфера
    11. mov ecx,SIZEOF buffer - 1              ;загрузим максимальное количество символов
    12. call ReadString                        ;введем строку А
    13. mov edx,OFFSET buffer                  ;отобразим введенную строку А
    14. call CrLf
    15. call WriteString
    16. call ReadChar                       ;получим позицию, с которой присоединим второю строку
    17. mov number,al
    18. mov eax,number
    19. mov ecx,SIZEOF buffer - 1  
    20. mov esi,0
    21. L1:
    22. mov al,buffer[esi]
    23.  
    24. inc esi
    25. cmp eax,ecx
    26. jl L1
    27. mov edx, OFFSET buffer
    28.             ;отобразим полученную строку A
    29. call WriteString
    30. call CrLf
    31. call WaitMsg
    32. exit
    33. main ENDP
    34. END main
    Ругается на строчку
    Код (Text):
    1. cmp eax,ecx
    и выдает ошибку assembler.asm(60) : error A2070: invalid instruction operands. Ведь cmp позволяет операцию register, register..Помогите пожалуйста)
     
  2. asmlamo

    asmlamo Active Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    1.574
  3. Serjuk

    Serjuk New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2011
    Сообщения:
    17
  4. kernel16

    kernel16 Human Vl

    Публикаций:
    0
    Регистрация:
    29 окт 2010
    Сообщения:
    317
    а метки начала выполнения программы нету?(Begin:)
     
  5. Serjuk

    Serjuk New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2011
    Сообщения:
    17
    а надо ? тут ведь же .code main PROC и в конце exit main ENDP END main
     
  6. kernel16

    kernel16 Human Vl

    Публикаций:
    0
    Регистрация:
    29 окт 2010
    Сообщения:
    317
    надо, Вася, надо(с).
    объяви в нач через Begin, не надо юзать main несколько раз
    .code
    fn1_a proc ddfff:dword
    xor eax,eax
    ret
    fn1_a endp
    fn2_a proc ddfff:dword
    xor eax,eax
    dec eax
    ret
    fn2_a endp

    Begin:
    Main proc
    push dword ptr 0
    call fn1_a
    push dword ptr 2
    call fn2_a
    ret
    Main endp
    end Begin
     
  7. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    kernel16
    не путайте человека, всё он правильно написал
    Но я бы не стал всё же точку входа ставить на процедуру. Пусть лучше указывает на глобальную метку, за которой стоит вызов основной процедуры, либо просто избавиться от proc/endp.
     
  8. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Serjuk
    говорит о том, что ошибка в шестидесятой строке, а у Вас в исходнике их 34. В чём подвох?
    И прокомментируйте, пожалуйста, что вы хотите добиться в цикле, ибо там какой-то, простите, бред.
     
  9. asmlamo

    asmlamo Active Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    1.574
    Он что то скрывает :)
     
  10. LShadow77

    LShadow77 New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2010
    Сообщения:
    36
    И напрасно.

    Если кто забыл, имя процедуры в MASM также является и меткой, так что вставлять ещё одну нет никакой необходимости. Другое дело, что функция main() подразумевает наличие аргументов argc,argv. В C++ она вызывается из стартапа, но сама не является стартовой. Поэтому лучше использовать имя Start, а не main:

    Start proc
    .................
    бла-бла-бла
    .................
    exit
    Start endp
    end Start

    Так где 60-я строка? )))

    Вообще-то, movzx eax,number!

    А в цикле - полный бред, проц сломается.
     
  11. Serjuk

    Serjuk New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2011
    Сообщения:
    17
    я просто код неполностю выложил ) так как программу еще не дописал
    В цикле хочу обрезать строку элементов с заданного номера в этой строке. Т.е. если задать позицию 4 и строку aabbcc то на выходе должны получить aabb
    вот полный
    Код (Text):
    1. TITLE laba_assembler (laba_assembler.asm)
    2.  
    3. INCLUDE Irvine32.inc
    4. LF = 0Ah ; перевод строки
    5. CR = 0Dh ;возврат каретки
    6.  
    7. BUFMAX = 128 ; максимальный размер буфера
    8. .data
    9.   str1 BYTE "vvedite dannyy ctroky A:",CR,LF,0
    10.   str3 BYTE "vvedite dannyy podctroky B:",CR,LF,0
    11.   str2 BYTE "vvedite cimvol c kotorogo prouzoudet podcoedinenie ctroki B k ctroke A:", CR,LF,0
    12. ; str3 BYTE "Polychennaya ctroka:",CR,LF,0
    13.  buffer BYTE BUFMAX DUP(0)
    14. buffer1 BYTE BUFMAX DUP(0)
    15.  ;ArrayString BYTE 50 DUP(0)
    16. ;String BYTE ?
    17. ;myString BYTE ?
    18.  number BYTE ?
    19. .code
    20. main PROC                              
    21.  
    22.  call ClrScr                           ;очистить экран
    23. mov edx, OFFSET str1                   ;выведем на экран строку str1
    24. call WriteString
    25. mov edx,OFFSET buffer                  ;загрузим адрес буфера
    26. mov ecx,SIZEOF buffer - 1              ;загрузим максимальное количество символов
    27. call ReadString                        ;введем строку А
    28. mov edx,OFFSET buffer                  ;отобразим введенную строку А
    29. call CrLf
    30. call WriteString
    31. ;--------------------------
    32.  
    33. mov edx,OFFSET str2                    ;выведем на экран строку str2          
    34. call WriteString                  
    35. call ReadChar                       ;получим позицию, с которой присоединим второю строку
    36. mov number,al
    37. ;call WriteChar
    38. ;----------------------
    39.  
    40.  
    41.  
    42.  
    43. ;mov edx, OFFSET str3                  ;выведем на экран строку str2
    44. ;call WriteString
    45. ;mov edx,OFFSET buffer1                  ;загрузим адрес буфера
    46. ;mov ecx,SIZEOF buffer1 - 1              ;загрузим максимальное количество символов
    47. ;call ReadString                        ;введем строку А
    48. ;mov edx,OFFSET buffer1                  ;отобразим введенную строку B
    49. ;call WriteString
    50.  
    51. ;---------------цикл копирования-----
    52. mov eax,number
    53. mov ecx,SIZEOF buffer - 1  
    54. mov esi,0
    55. L1:
    56. mov al,buffer[esi]
    57.  
    58. inc esi
    59. cmp eax,ecx
    60. jl L1
    61. mov edx, OFFSET buffer
    62.  
    63. call WriteString
    64.  
    65.  
    66.  
    67.  
    68. call CrLf
    69. call WaitMsg
    70. exit
    71. main ENDP
    72. END main
     
  12. LShadow77

    LShadow77 New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2010
    Сообщения:
    36
    Так в чём проблема? Я так понял, что строка загружается в массив buffer с длиной BUFMAX. Допустим искомая позиция в переменной Position типа DWORD, тогда:
    Код (Text):
    1.         mov     ecx,BUFMAX
    2.         mov     edx,ecx
    3.         mov     edi,offset buffer
    4.         xor     eax,eax
    5.         repne scasb       ;ищем конец строки
    6.         jne     OutOfBuf  ;защита от выхода за пределы буфера
    7.         sub     edx,ecx
    8.         dec     edx       ;в EDX - длина строки
    9.         mov     ecx,Position
    10.         cmp     ecx,edx
    11.         ja      OutOfStr  ;позиция больше длины строки
    12.         mov     buffer[ecx],al  ;собственно обрезаем строку
    13.         jmp     Next
    14.  
    15. OutOfBuf:
    16.         бла-бла-бла
    17.         jmp     Next
    18.  
    19. OutOfStr:
    20.         бла-бла-бла
    21.  
    22. Next:
    23.         ....................
     
  13. Serjuk

    Serjuk New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2011
    Сообщения:
    17
    Попробовал:
    Код (Text):
    1. TITLE laba_assembler (laba_assembler.asm)
    2.  
    3. INCLUDE Irvine32.inc
    4. LF = 0Ah ; перевод строки
    5. CR = 0Dh ;возврат каретки
    6.  
    7. BUFMAX = 128 ; максимальный размер буфера
    8. .data
    9.   str1 BYTE "vvedite dannyy ctroky A:",CR,LF,0
    10.   str3 BYTE "vvedite dannyy podctroky B:",CR,LF,0
    11.   str2 BYTE "vvedite cimvol c kotorogo prouzoudet podcoedinenie ctroki B k ctroke A:", CR,LF,0
    12. ; str3 BYTE "Polychennaya ctroka:",CR,LF,0
    13.  buffer BYTE BUFMAX DUP(0)
    14. buffer1 BYTE BUFMAX DUP(0)
    15.  
    16.  
    17. Position DWORD ?
    18. .code
    19. main PROC                              
    20.  
    21.  call ClrScr                           ;очистить экран
    22. mov edx, OFFSET str1                   ;выведем на экран строку str1
    23. call WriteString
    24. mov edx,OFFSET buffer                  ;загрузим адрес буфера
    25. mov ecx,SIZEOF buffer - 1              ;загрузим максимальное количество символов
    26. call ReadString                        ;введем строку А
    27. mov edx,OFFSET buffer                  ;отобразим введенную строку А
    28. call CrLf
    29. call WriteString
    30. ;--------------------------
    31.  
    32. mov edx,OFFSET str2                    ;выведем на экран строку str2          
    33. call WriteString                  
    34. call ReadChar                   ;получим позицию, с которой присоединим второю строку
    35. mov Position,al
    36. ;call WriteChar
    37. ;----------------------
    38.  
    39.  
    40.  
    41.  
    42. ;mov edx, OFFSET str3                  ;выведем на экран строку str2
    43. ;call WriteString
    44. ;mov edx,OFFSET buffer1                  ;загрузим адрес буфера
    45. ;mov ecx,SIZEOF buffer1 - 1              ;загрузим максимальное количество символов
    46. ;call ReadString                        ;введем строку А
    47. ;mov edx,OFFSET buffer1                  ;отобразим введенную строку B
    48. ;call WriteString
    49.  
    50. ;---------------цикл копирования-----
    51.  
    52. mov     ecx,BUFMAX
    53.         mov     edx,ecx
    54.         mov     edi,offset buffer
    55.         xor     eax,eax
    56.         repne scasb       ;ищем конец строки
    57.         jne     OutOfBuf  ;защита от выхода за пределы буфера
    58.         sub     edx,ecx
    59.         dec     edx       ;в EDX - длина строки
    60.         mov     ecx,Position
    61.         cmp     ecx,edx
    62.         ja      OutOfStr  ;позиция больше длины строки
    63.         mov     buffer[ecx],al  ;собственно обрезаем строку
    64.         jmp     Next
    65.  
    66. OutOfBuf:
    67.        ; бла-бла-бла
    68.         jmp     Next
    69.  
    70. OutOfStr:
    71. ;        бла-бла-бла
    72.  
    73. Next:
    74.  
    75.  
    76. mov edx, OFFSET buffer
    77.  
    78. call WriteString
    79.  
    80.  
    81.  
    82.  
    83. call CrLf
    84. call WaitMsg
    85. exit
    86. main ENDP
    87. END main
    выдает ошибку :
    ругается на строчку mov Position,al
     
  14. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    Serjuk
    Код (Text):
    1. mov Position, al
    Position - DWORD
    al - BYTE
    Код (Text):
    1. and eax, 0x000000FF
    2. mov Position, eax
     
  15. Serjuk

    Serjuk New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2011
    Сообщения:
    17
    заменил строчку
    Код (Text):
    1. mov Position,al
    на
    Код (Text):
    1. and eax, 0x000000FF
    2. mov Position, eax
    и теперь ругается на:
    Код (Text):
    1. and eax, 0x000000FF
    говорит:
    assembler.asm(38) : error A2206: missing operator in expression
     
  16. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.552
    Адрес:
    Russia
    max7C4
    да, никто не хочет заморачиваться парсингом введенной строки с целью получить dword :)
     
  17. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    Serjuk
    0x000000FF это $000000FF или просто 255
     
  18. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.552
    Адрес:
    Russia
    Serjuk
    and eax,0FFh
     
  19. asmlamo

    asmlamo Active Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    1.574
    >ругается на строчку mov Position,al

    Я бы на месте компилятора убивал за такое :)
     
  20. asmlamo

    asmlamo Active Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    1.574
    >and eax, 0x000000FF

    and eax, 000000FFh

    >mov Position, al

    mov byte ptr [Position], al