【问题标题】:Nasm print to next lineNasm 打印到下一行
【发布时间】:2016-04-27 05:48:05
【问题描述】:

我有以下用 nasm 汇编编写的程序:

section .text
    global _start:

_start:
    ; Input variables
    mov edx, inLen
    mov ecx, inMsg
    mov ebx, 1
    mov eax, 4
    int 0x80

    mov edx, 2
    mov ecx, num1
    mov ebx, 0
    mov eax, 3
    int 0x80

    mov edx, inLen
    mov ecx, inMsg
    mov ebx, 1
    mov eax, 4
    int 0x80

    mov edx, 2
    mov ecx, num2
    mov ebx, 0
    mov eax, 3
    int 0x80

    ; Put input values in correct registers
    mov eax, [num1]
    sub eax, '0'    ; convert char to num
    mov ebx, [num2]
    sub ebx, '0'    ; convert char to num

    ; Perform addition
    add eax, ebx
    add eax, '0'    ; convert num to char

    ; Set sum in res
    mov [res], eax

    ; Output result
    mov edx, resLen
    mov ecx, resMsg
    mov ebx, 1
    mov eax, 4
    int 0x80

    mov edx, 1
    mov ecx, res
    mov ebx, 1
    mov eax, 4
    int 0x80

    ; Exit program
    mov eax, 1
    int 0x80

    section .bss
    num1    resb 2
    num2    resb 2
    res resb 2

section .data
    inMsg db "Input number: ", 0xA, 0xD
    inLen equ $-inMsg
    resMsg db "Result: ", 0xA, 0xD
    resLen equ $-resMsg

当我运行它时,控制台看起来像这样:

tyler@ubuntu:~/ASM/Addition$ ./Add 
Input number: 
3
Input number: 
2
Result: 
5tyler@ubuntu:~/ASM/Addition$ 

我怎样才能得到它,以便 5 将打印在自己的行上,而不是在它之后直接打印 cmd? IE。它应该是这样的:

tyler@ubuntu:~/ASM/Addition$ ./Add 
Input number: 
3
Input number: 
2
Result: 
5
tyler@ubuntu:~/ASM/Addition$ 

【问题讨论】:

  • 打印结果后将字符序列0xA, 0xD写入stdout。
  • 是linux,写0xA.

标签: linux assembly x86 nasm


【解决方案1】:

您已经掌握了所有信息,只是还没有看到:

resMsg db "Result: ", 0xA, 0xD

你知道这到底是什么意思吗?它定义了一个由以下字符组成的字符串:

Result: XY

...其中 XY 实际上是不可见字符(数值为 0xA=10 和 0xD=13,也称为换行符 (LF) 和回车符 (CR)),它们会导致输出换行。由于它们的不可见性质,它们被指定在双引号之外 - 您不能只将它们包含在其中,因此您必须改写它们的数值。

当然你也可以单独使用它们:

newLineMsg db 0xA, 0xD
newLineLen equ $-newLineMsg

newLineLen 当然是 2,但我把它留在这里是为了让系统与您当前使用的系统相同,以便于理解。)

所以要输出一个没有任何其他文本的换行符(你想在5之后做的事情),你可以使用:

mov edx, newLineLen
mov ecx, newLineMsg
mov ebx, 1
mov eax, 4
int 0x80

...就像resMsg/resLen.


但是,正如 Jester 指出的那样,在 Linux 上,您还应该能够只输出一个换行符 (0xA)(并且还可以从代码中删除现有的 0xD)。

【讨论】:

  • 您不需要单独的换行符。只需在 resMsg 的换行符上添加标签即可。还值得指出的是,它们都应该在 .rodata 部分。
  • 此外,NASM(但不是 YASM)将处理反引号字符串中的 C 样式 \n,因此您可以使用它而不是数字值进行 ASCII 编码。
  • @PeterCordes:我运行了以下代码:[](gist.github.com/anonymous/ecba3950faa63a4fff4d4573bbc8d0d2)。我使用 nasm ($nasm -f elf Hello.asm $ld -m elf_i386 -s -o Hello Hello.o ) 编译它,但是当我运行脚本时,我的控制台看起来像这样:tyler@ubuntu:~/ASM/HellowWorld$ ./Hello Hello World\ntyler@ubuntu:~/ASM/HellowWorld$.... 我是不是做错了什么,因为看起来 c 样式不起作用?
  • @TylerHilbert:您可能将字符串常量放在双引号而不是反引号中。 nasm.us/doc.
  • @TylerHilbert:这就是问题所在。 db "Hello World", 0xA, 0x0 有效,db `Hello World\n`, 0 仅在 NASM(不是 YASM)中有效。此时仅使用 ASCII 换行符的数值可能会更清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-16
  • 2016-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多