assembly 汇编语言程序循环,打印消息

9gm1akwq  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(176)

因此,理想情况下,我希望这个程序运行一个msg中的所有字符。例如,“Hey there”,有10个字符。它将迭代10次。(我假设像C一样,你必须考虑到空间)
我硬编码了这些值,因为我很难弄清楚如何让它读取这个字符串中的字符数。我试过我的代码,它会运行一次,然后等待我在终端中做一些事情。或者它会出现seg错误(我已经尝试了大约100次,每次都是不同的方式)
我做错了什么?我觉得这是一件很简单的事情,我只是忽略了!我试图使用调试器来找出我做错了什么,但我是第一次组装,所以我有点困惑。所以,如果你能解释一下“计算机”在做什么,这将帮助很大!
这是我的代码:

section .text   
    global _start

_start:
   mov  edx, 13  ;;message to write
   mov  ecx, msg     ;message length
   mov  ebx,1       ;file descriptor (stdout)
   mov  eax,4       ;system call number (sys_write)
   int  0x80        ;trigger system call


mov ax, 13

loop_top:
    cmp ax, 13
    je loop_top

section .data
        
    msg  db  'Hello there!' ,0xa;the string of we want to pass
    ;;len  equ  $ - msg         ;length of our string
ttisahbt

ttisahbt1#

如果你想找到一个字符串的长度,你可以做以下。
首先,确保你的字符串在结尾有一个标识符,它让你知道你的字符串已经结束了,空终止符在大多数语言中是默认的(例如在C中)。

str db "Hello, world!", 0x00

然后你需要迭代这个字符串,直到你达到0x00

findStringLength:
    mov cx, 0x00 ; lets keep a count on the character

iterate:    
    mov bx, str ; get the address of the string
    add bx, cx ; add the character count that we kept

    mov al, byte[bx] ; put the iterated character inside al
    cmp al, 0x00 ; check if we reached the end of string
    je endIteration ; end iteration if we did.
 
    ; do something with character in al
    ; ...
    ;

    inc cx ; increase the iterator
    jmp iterate ; loop

endIteration:
    mov ax, cx ; return the length in ax
    ret

这段代码是一个模板,但您可以理解

a11xaf1n

a11xaf1n2#

就像你说的,你忽略了一件很简单的事情。不要难过--我都不知道我这样做了多少次了。
问题就在这里:

mov ax, 13

loop_top:
    cmp ax, 13
    je loop_top

你把ax设为13,然后你一遍又一遍地检查,直到它不再是13。因为AX的值没有改变,所以je loop_top总是被执行,你就永远循环下去了。如果那个分支不被执行......你看,即使我们声明了section .data,CPU不够聪明,不能知道那是数据而不是指令。seg错误的发生很可能是因为CPU试图自己执行字符串,就好像它是指令一样。在汇编语言中,你键入的顺序是非常字面上的。

section .text   
    global _start

_start:
   mov eax, len         ;message length
loop_top:
   push eax
       mov  edx, msg    ;message to write
       mov  ecx, len    ;message length
       mov  ebx,1       ;file descriptor (stdout)
       mov  eax,4       ;system call number (sys_write)
       int  0x80        ;trigger system call
   pop eax
   dec al               ;subtract 1 from AL
   jnz loop_top         ;if nonzero, do it again

   
   ;;your exit syscall needs to go here or you'll segfault.

section .data
        
    msg  db  'Hello there!' ,0xa;the string of we want to pass
    len  equ  $ - msg         ;length of our string

这不是最佳的方法,但它是一个快速和肮脏的例子。

相关问题