2011-08-04 74 views
1

正如你所想的那样,我对这件事很陌生(包括nasm和assembly,尽管我之前做过一些基本的汇编)。
我想创建一个打印整数到标准输出的函数。使用不可重用的代码(其中要打印的数字是静态的),我已经成功......但是,由于显而易见的原因,我希望它将该数字打印为参数。在nasm宏中创建缓冲区?

我不确定一个宏还是一个函数对我来说是最好的,我根本找不到关于NASM宏的主题。我已经仔细阅读了手册,但这还不够。

无论如何,我试图用NASM宏来做这件事,因为我创建了另一个以这种方式打印成功的字符串。
我已经缩小问题代码这样:

%macro crash 1 
jmp %%endstr 
%%str: db %1,0x0a 
%%endstr: 
mov [%%str], byte 0x16 <<< this crashes (segmentation fault) 
%endmacro 

section .text 
global _start 
_start: 
crash "abc" 

它看起来像在缓冲崩溃使用括号任何东西,我只能假设我这样做是错误的。
我想要上面要做的是用另一个字节值覆盖%% str中的第一个字节。更确切地说,我需要将字符串逐字节地向后写入缓冲区;我(尝试)这样做有一个循环,我在那里做

mov [%%str+rcx], dl 
dec rcx 

直到RCX为0

如果我不应该使用宏对于这一点,请赐教!
我打算将该功能保存在一个小型库中供以后使用,因此应该很容易将它弹出到任何NASM项目中。

正如主题和标签所说,所有这些都在Linux/amd64下。

+0

你应该让这样的功能,其宏展开内部状态各地你的代码是不好的风格(甚至汇编!)。它也将有助于您的调试。如果你需要更多的帮助来解决你的问题,你应该发布gdb('gdb。/ your-program')的所有相关代码和输出,并捕获'bt'和'info reg'的输出。 – user786653

回答

4

你不能在代码段中这样做,因为它是只读的。你应该在@data段声明str,那么你会没事的。而且,就像@ user786653所说的那样,“你应该让这个函数成为一个函数,让宏在你的代码中传播内部状态是糟糕的风格(即使是汇编器!)”。

+0

该死的,我是如何忽略数据代码段的隐式使用?在老的汇编程序代码中查看太多无关紧要的事情我会猜测:) +1由于这几乎肯定是正确的答案。 – user786653

+0

谢谢,现在你说我记得。我应该再次通过基础知识。无论如何,这有点令人困惑:[this code](https://gist.github.com/a0b75f5a28a2d079ffb7)以相同的方式存储数据!我认为这只是一种侥幸,而不是我应该考虑使用代码的东西,然后呢? – exscape

+2

@exscape:该代码不写入字符串。您可以在代码段中拥有只读数据,但您不能(不应该)在那里写入数据。 – user786653

0

for in section .data

;在部分使用字节

%macro BUFFER 2 
%1: 
    .start: times %2 db 0 
    .end: 
    .length: equ %1.end-%1.start 
%endmacro 

的姓名和电话号码为的.bss

;使用名称和字节数这里

%macro BUFFER 2 
%1: 
    .start: resb %2 
    .end: 
    .length: equ %1.end-%1.start 
%endmacro 

问题是我们想知道缓冲区的最后一个字节则是buffer.end- 一个可能的解决方案,但我没有尝试它尚未:

%macro BUFFER 2 
%1: 
    .start: times %2-1 db 0 
    .end: db 0 
    .length: equ %1.end-%1.start 
%endmacro 

同上的.bss段

%macro BUFFER 2 
%1: 
    .start: resb %2-1 
    .end: resb 1 
    .length: equ %1.end-%1.start 
%endmacro 
相关问题