assembly - 如何替换Nasm程序中的特定字符

标签 assembly nasm x86-16

我想用“#”字符替换 dbyte 中的空格,并且 db 应通过堆栈传递给过程。

我已经编写了下一个代码片段,并且替换工作正常,但我无法理解如何正确地将数据库传递给过程func

org 0x100 
    push array
    call func
    mov bp, sp 
    mov bx, [bp]
    ret 

loop:
    mov al, byte[bx+si]
    cmp al, 0
     jz func
    cmp al , ' '
     jnz loop
    mov byte[bx+si], '#'
    inc si
    jmp loop
    ret

func:  
    push bp  
    mov bp, sp  
    mov bx, [bp + 4]    
    call loop
    mov [bp + 4], bx
    pop bp  
    ret 4 

array db "a b c", 0

最佳答案

几个问题

push array
call func
;
ret 4

这是 16 位代码,因此数组被作为一个单词推送。 ret 4 应改为 ret 2。请注意,您的数组实际上是一个以零结尾的字符串

mov al, byte[bx+si]

如果您事先没有清除SI,此操作将无法工作。

cmp al, 0
jz func

您正在使用您调用的代码。您不应该像这样跳回调用者!

cmp al , ' '
jnz loop

到顶部的跳转错过了 SI 上的增量。

mov [bp + 4], bx

这是多余的,因为参数没有被修改。而且无论如何你都会丢弃它。

mov bp, sp 
mov bx, [bp]

这个有用吗?它只是加载随后的程序终止的返回地址。

ret

这种终止程序的方式依赖于正确的堆栈。情况并非总是如此! DOS 程序最好通过以下方式终止:

mov ax, 4C00h
int 21h
<小时/>

将其放在一起

 org  256

 push MyString
 call Func
 mov  bp, sp 
 mov  bx, [bp]
 mov  ax, 4C00h  ;Program termination
 int  21h

Loop:
 mov  al, byte[bx+si]
 cmp  al, 0
 je   EndOfLoop
 cmp  al, ' '
 jne  NotASpace
 mov  byte[bx+si], '#'
NotASpace:
 inc  si
 jmp  Loop
EndOfLoop:
 ret

;Clobbers AL, BX, SI
Func:  
 push bp  
 mov  bp, sp  
 mov  bx, [bp + 4]
 xor  si, si
 call Loop
 pop  bp  
 ret  2

MyString db "a b c", 0

关于assembly - 如何替换Nasm程序中的特定字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56712860/

相关文章:

assembly - 在 Art of Exploitation 示例中被 [ebp-0xc] 而不是 [ebp-4] 混淆

linux - 拆卸和重新组装,如何在终端中正确地进行管道传输?

delphi - 为什么某些汇编指令没有记录在案

linux - 如何避免不适合缓冲区的标准输入被发送到 Linux 64 位 Intel (x86-64) 程序集中的 shell

assembly - 基址指针和堆栈指针

assembly - EMU8086 是否有错误,或者我编写此代码时犯了错误?

c - 解释 AF 标志在 x86 指令中的工作原理?

linux - 组装 NASM - AND 掩模

assembly - 区分无符号与正负二进制数

assembly - UEFI 机器可以使用 BIOS 中断吗?