Сборка x86 32 бит / обратный и добавление строки - PullRequest
0 голосов
/ 03 декабря 2011

Я хочу перевернуть строку в сборке х-86.смысл - если я получил "1234", я хочу, чтобы мой результат был "4321".Я думаю, чтобы положить каждый символ в стек, и вытолкнуть их.Но я не знаю, чтобы реализовать это. Мне нужен буфер для этого?(Я могу переопределить оригинальную строку).

Ответы [ 3 ]

2 голосов
/ 03 декабря 2011

Примерно так может работать (при условии 32-битного режима, написанного с использованием синтаксиса NASM):

; finding string length:
mov ebx, mystr ; current position within the string
mov ecx, 0 ; current string length

l1:
mov al, [ebx] ; fetch a character from the string
cmp al, 0 ; is this string end?
je l2 ; yes, it is

inc ebx ; increment the position from where we'll read next character
inc ecx ; increment length
jmp l1 ; repeat

l2: ; ecx = string length

; reversing the string:
cmp ecx, 2 ; is the string too short?
jb l4 ; yes, it has 0 or 1 chars, we're done

mov ebx, mystr ; ebx points to the first char in the string
lea edx, [ebx+ecx-1] ; edx = ebx+ecx-1 - points to the last char in the string
shr ecx, 1 ; ecx = half the string length

l3:
mov al, [ebx]
xchg al, [edx]
mov [ebx], al ; [ebx] and [edx] swapped
inc ebx ; advance head pointer
dec edx ; advance tail pointer
loop l3 ; decrement ecx and if ecx isn't 0, repeat

l4:
;...

; string (NULL-terminated):
mystr db '1','2','3','4',0
1 голос
/ 03 декабря 2011

Вы можете сделать это с одним из абстрактных типов данных (например, стеком или очередью), но зачем?

Просто используйте два указателя, один в начале и один в конце, а затем поменяйте местамиони указывают на.Увеличьте начальный указатель и уменьшите конечный, затем продолжайте, пока они не встретятся или не пересекутся.

В следующем коде (псевдокод, поскольку (1) это звучит немного как домашнее задание и (2) его легко преобразовать влюбой процедурный язык), я буду считать строки в стиле C, но вы можете легко приспособиться к другим вариантам.Псевдокода, подобного следующему, будет достаточно, при условии, что у вас есть доступ к значению, address of first character:

set pstart to address of first character

# Locate last character
set pend to pstart
while [pend] is not null:
    pend = pend + 1
pend = pend - 1

# Continue until they cross
while pstart < pend:
    # Swap contents
    tmp = [pstart]
    [pstart] = [pend]
    [pend] = tmp

    # Move pointers
    pstart = pstart + 1
    pend = pend - 1

Если вы действительно хотите использовать ADT, стека будет достаточно сследующая логика:

# Push until reached end of string
set pchar to address of first character
while [pchar] is not null:
    push [pchar]
    pchar = pchar + 1

# Then pop the same way (but reverse order)
set pchar to address of first character
while [pchar] is not null:
    pop [pchar]
    pchar = pchar + 1
0 голосов
/ 05 декабря 2011

Не знаю, как вы отслеживаете исходную строку, но я делал нечто подобное давным-давно.Самый простой (но не оптимальный по скорости) способ, предполагающий, что вы берете ввод с клавиатуры, состоит в том, чтобы иметь буфер, помещать его в буфер с флагом направления по умолчанию, затем после завершения ввода перевернуть флаг направления, настроить регистры и затемlodsb ... При необходимости адаптируйтесь в зависимости от того, откуда исходит ваша строка.

...