首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >汇编语言修改输入字符串错误

汇编语言修改输入字符串错误
EN

Stack Overflow用户
提问于 2016-04-07 01:30:36
回答 1查看 304关注 0票数 0

我试图在Linux上编写一个32位的x86 NASM程序,它接收文本文件中的字符串,编码将字符串中的所有字符向上移动1,并将其输出到控制台。几乎所有的东西都能工作,除了循环.rot132,它用来做移位和printf。每当.rot132被调用时,它都会给出一个segmentation_fault(核心转储)。我想当我移动ecx, [eax]时,它会引起某种错误。我怎样才能克服这部分呢?

代码语言:javascript
复制
;;sddddddddddddddddgsd

[SECTION .data] ; Section containing initialized data

WriteCode db "w",0
OpenCode db "r",0
Filename db "text.txt",0
fileFmt: dd "%c\n",10,0
fileFmt1: dd "%s",10,0

[SECTION .bss] ; Section containing uninitialized data
TextLenght EQU 72 ; Define length of a line of  text data
Text resb TextLenght ; Reserve space for disk-based help text line
BUFSIZE EQU 64 ; Define length of text line buffer 
Buff resb BUFSIZE+5 ; Reserve space for a line of text

[SECTION .text] ; Section containing code
;; These externals are all from the glibc standard C library:
extern fopen
extern fclose
extern fgets
extern fprintf
extern printf
extern sscanf
extern time

global main ; Required so linker can find entry point

main:

diskhelp:
        mov  ebx, Filename ; push file name to ebx
        push OpenCode ; Push pointer to open-for-read code “r“
        push ebx ; Pointer to name of help file is passed in ebx
        call fopen ; Attempt to open the file for reading
        add esp,8 ; Clean up the stack
        cmp eax,0 ; fopen returns null if attempted open failed
        jne .disk ; Read help info from disk file...
        ret

.disk:  mov ebx,eax ; Save handle of opened file in ebx

.rdln:  push ebx ; Push file handle on the stack
        push dword TextLenght ; Limit line length of text read
        push Text ; Push address of text line buffer
        call fgets ; Read a line of text from the file
        add esp,12 ; Clean up the stack
        ;cmp eax,0 ; A returned null indicates error or EOF
        ;jle .rot13 ; If we get 0 in eax, close up & return

        ;push Text ; Push address of help line on the stack
        ;call printf ; Call printf to display help line
        ;add esp,4 ; Clean up the stack

.rot131: ; initial shift and test, this work
        mov edx, 0    ; our counter
        mov eax, Text ; move string into eax
        mov ecx, [eax]; move first char in string into ecx
        add ecx, 1    ; shift the char up by 1 
        push ecx      ; push to print
        push fileFmt
        call printf
        add esp, 8   ; clear the stack
        inc edx      ; increase the counter

.rot132: 
        inc eax     ; shift address of eax into next char
        mov ecx, [eax] ; move the char into ecx, replace old char; error ??
        add ecx, 1     ; shift the char by 1
        push ecx        ; print
        push fileFmt
        call printf
        add esp, 8      ; clear the stack
        inc edx         ;incrase counter
        cmp edx,4       ; stop loop after edx = 4 
        jne .rot132


        push ebx ; Push the handle of the file to be closed
        call fclose ; Closes the file whose handle is on the stack
        add esp,4 ; Clean up the stack

        ret ; Go home

gdb调试:反汇编.rot132:

代码语言:javascript
复制
   0x08048559 <+0>:     inc    %eax
   0x0804855a <+1>:     mov    (%eax),%ecx
   0x0804855c <+3>:     add    $0x1,%ecx
   0x0804855f <+6>:     push   %ecx
   0x08048560 <+7>:     push   $0x804a035
   0x08048565 <+12>:    call   0x80483b0 <printf@plt>
   0x0804856a <+17>:    add    $0x8,%esp
   0x0804856d <+20>:    inc    %edx
   0x0804856e <+21>:    cmp    $0x4,%edx
   0x08048571 <+24>:    jne    0x8048559 <rot132>
   0x08048573 <+26>:    push   %ebx
   0x08048574 <+27>:    call   0x80483d0 <fclose@plt>
   0x08048579 <+32>:    add    $0x4,%esp
   0x0804857c <+35>:    ret
   0x0804857d <+36>:    xchg   %ax,%ax
   0x0804857f <+38>:    nop
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-07 02:20:29

fileFmt应该是db,而不是dd。你在定义双字字符。

请注意,此代码不如编译器生成的代码好。只需要使用汇编语言进行关键循环,这是配置文件顶部明显的CPU瓶颈,而且您已经使用了一个很好的算法。

一个例子是矩阵乘法。它是令人尴尬的平行,所以强制编译器使用最有效的方法来执行操作通常是有益的,例如使用向量扩展,比如SSE。

编译器是如此优秀,以至于您通常用内部语言编写“汇编语言”,例如SSE或AVX,它们允许编译器担心数据流和寄存器分配,并允许您专注于指令本身。

还请注意Michael的好评论:允许打电话来打击eaxecxedx。你可以相信他们会保存ebxesiediebpesp。这意味着您需要停止对变量使用ecxedx,并使用一些保存下来的东西,比如ebxediesiebp

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36465152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档