如何用汇编语言反转和打印字符串 [英] How to reverse and print a string in assembly language

查看:387
本文介绍了如何用汇编语言反转和打印字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我的任务是用汇编代码编写一个程序,该程序可以发表声明,并接收用户输入的字符串.打印该字符串,然后使用cpu堆栈将其反转,然后再次打印.这就是我到目前为止所拥有的.

INCLUDE Irvine32.inc

.data
buffer byte 20 DUP(0)
byteCount DWORD ?

Question  byte  "Please enter your name."  ,0
Greeting byte   "Hello " ,0
Statement byte " Here is your name backwards"

.code
main proc


mov edx , OFFSET Question
call WriteString
call CRLF
Call CRLF

mov edx, OFFSET buffer
mov Ecx, SIZEOF buffer
call ReadString

push edx
mov EDX ,OFFSET greeting
Call WriteString
pop edx
call WriteString
Call CRLF
Call CRLF

如您所见,此操作成功接受了用户输入的输入并显示了该输入,但是我真的很努力地尝试将其撤消.

我在这里尝试过这些,是我从一本书中从反转字符串的一章复制过来的.

; Push the name on the stack.

mov ecx,nameSize
mov  esi,0

L1: movzx eax,aName[esi]    ; get character
push eax                ; push on stack
inc  esi
loop L1

; Pop the name from the stack in reverse
; and store it in the aName array.

mov  ecx,nameSize
mov  esi,0

L2: pop  eax                ; get character
mov  aName[esi],al      ; store in string
inc  esi
loop L2

Invoke ExitProcess,0
main endp
end main

但我没有得到任何输出.

它说你好,(你的名字在这里)"

它说这是你的名字倒退"

ive几乎尝试了所有我能想到的这种化身,但无济于事.我在我的字符串"结尾处

解决方案

这与我更好的判断相反,因为用于反转的代码片段甚至还没有集成到原始张贴者创建的代码中.变量名称不同.快速,肮脏的代码集成是创建一个变量 nameSize ,该变量保存从对 ReadString 的调用中读取的字符数. ReadString (Irvine32库的一部分)返回字符在寄存器 EAX 中读取.

.data部分中添加变量:

nameSize  DWORD ? 

在ReadString将 EAX 的内容移动到nameSize之后.这段代码:

mov edx, OFFSET buffer
mov Ecx, SIZEOF buffer
call ReadString

应该是:

mov edx, OFFSET buffer
mov Ecx, SIZEOF buffer
call ReadString
mov nameSize, eax       ; EAX contains number of characters read into buffer

在用于反转代码的代码片段中,删除程序结尾等底部的行.由于我们将在原始代码中执行此操作,因此不需要这些行.

Invoke ExitProcess,0
main endp
end main

在字符串反转代码中的每个地方,我们看到变量 aName 都会将其更改为 buffer ,因为这是我们放置用户名的地方.将该代码放入我们的程序中,并使用WriteString在最后打印反转的缓冲区.该代码可能类似于:

INCLUDE Irvine32.inc

.data
buffer byte 20 DUP(0)
byteCount DWORD ?
nameSize  DWORD ?

Question  byte  "Please enter your name."  ,0
Greeting byte   "Hello " ,0
Statement byte " Here is your name backwards"

.code
main proc

    mov edx , OFFSET Question
    call WriteString
    call CRLF
    Call CRLF

    mov edx, OFFSET buffer
    mov Ecx, SIZEOF buffer
    call ReadString
    mov nameSize, eax

    push edx
    mov EDX ,OFFSET greeting
    Call WriteString
    pop edx
    call WriteString
    Call CRLF
    Call CRLF

    mov  ecx,nameSize
    mov  esi,0

L1: movzx eax,buffer[esi]    ; get character
    push eax                ; push on stack
    inc  esi
    loop L1

    ; Pop the name from the stack in reverse
    ; and store it in the aName array.

    mov  ecx,nameSize
    mov  esi,0

L2: pop  eax                ; get character
    mov  buffer[esi],al      ; store in string
    inc  esi
    loop L2


    mov EDX ,OFFSET buffer
    call WriteString         ; Write the reversed string that is now in buffer

    exit
main ENDP
END

如果遇到链接错误,则可能不是在所有必备库中都进行了链接.尝试将这些行添加到程序顶部:

INCLUDE Irvine32.inc
INCLUDELIB Irvine32.lib
INCLUDELIB user32.lib
INCLUDELIB kernel32.lib

我应该指出,如果您不介意破坏原始字符串,这是一种无效的反向字符串方式.通过在原处反转字符串,可以在堆栈上没有辅助缓冲区的情况下完成此操作.

So my assignment was to write a program in assembly code that could make a statement, recieve a user inputted string. Print that string then reverse it using the cpu stack and print it again. this is what I have thus far.

INCLUDE Irvine32.inc

.data
buffer byte 20 DUP(0)
byteCount DWORD ?

Question  byte  "Please enter your name."  ,0
Greeting byte   "Hello " ,0
Statement byte " Here is your name backwards"

.code
main proc


mov edx , OFFSET Question
call WriteString
call CRLF
Call CRLF

mov edx, OFFSET buffer
mov Ecx, SIZEOF buffer
call ReadString

push edx
mov EDX ,OFFSET greeting
Call WriteString
pop edx
call WriteString
Call CRLF
Call CRLF

As you can see this successfully accepts a user entered input and displays it but Im really struggling trying to reverse it.

I tried these here that I copied from the book from a chapter about reversing strings.

; Push the name on the stack.

mov ecx,nameSize
mov  esi,0

L1: movzx eax,aName[esi]    ; get character
push eax                ; push on stack
inc  esi
loop L1

; Pop the name from the stack in reverse
; and store it in the aName array.

mov  ecx,nameSize
mov  esi,0

L2: pop  eax                ; get character
mov  aName[esi],al      ; store in string
inc  esi
loop L2

Invoke ExitProcess,0
main endp
end main

but I get as output nothing.

it says "hello, (yourname here)"

it says "this is your name backwards "

ive tried just about every different incarnation of this I can think of and no avail. im at the end of my "string" here

解决方案

This is against my better judgement since the snippet of code for reversing hasn't even been integrated into the code the original poster created. The variable names differ. A quick and dirty integration of the code is to create a variable nameSize that holds the number of characters read from a call to ReadString. ReadString (part of the Irvine32 library) returns the number of characters read in register EAX.

In the .data section add the variable:

nameSize  DWORD ? 

After the ReadString move contents of EAX register to nameSize. This code:

mov edx, OFFSET buffer
mov Ecx, SIZEOF buffer
call ReadString

Should be:

mov edx, OFFSET buffer
mov Ecx, SIZEOF buffer
call ReadString
mov nameSize, eax       ; EAX contains number of characters read into buffer

In the code snippet for reversing code remove the lines off the bottom for the end of procedure etc. These aren't needed since we will do this in our original code.

Invoke ExitProcess,0
main endp
end main

Everywhere in the string reversal code where we see the variable aName change it to buffer since that is where we placed the user's name. Place that code into our program and use WriteString to print the reversed buffer at the end. The code could look something like:

INCLUDE Irvine32.inc

.data
buffer byte 20 DUP(0)
byteCount DWORD ?
nameSize  DWORD ?

Question  byte  "Please enter your name."  ,0
Greeting byte   "Hello " ,0
Statement byte " Here is your name backwards"

.code
main proc

    mov edx , OFFSET Question
    call WriteString
    call CRLF
    Call CRLF

    mov edx, OFFSET buffer
    mov Ecx, SIZEOF buffer
    call ReadString
    mov nameSize, eax

    push edx
    mov EDX ,OFFSET greeting
    Call WriteString
    pop edx
    call WriteString
    Call CRLF
    Call CRLF

    mov  ecx,nameSize
    mov  esi,0

L1: movzx eax,buffer[esi]    ; get character
    push eax                ; push on stack
    inc  esi
    loop L1

    ; Pop the name from the stack in reverse
    ; and store it in the aName array.

    mov  ecx,nameSize
    mov  esi,0

L2: pop  eax                ; get character
    mov  buffer[esi],al      ; store in string
    inc  esi
    loop L2


    mov EDX ,OFFSET buffer
    call WriteString         ; Write the reversed string that is now in buffer

    exit
main ENDP
END

If you get linking errors, you may not be linking in all the prerequisite libraries. Try adding these lines to the top of your program:

INCLUDE Irvine32.inc
INCLUDELIB Irvine32.lib
INCLUDELIB user32.lib
INCLUDELIB kernel32.lib

I should point out that this is a very inefficient way to reverse a string if you don't mind destroying the original. It can be done without a secondary buffer on the stack by reversing the string in place.

这篇关于如何用汇编语言反转和打印字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆