汇编语言作业,writeheader函数,调用Integer到ASCII函数

时间:2015-01-28 23:24:09

标签: c++ linux assembly

我正在上课,我们用汇编语言编程。我们刚刚开始,所以我对此很陌生,并且很难跟进。我们使用的是linux x64系统,我相信汇编程序叫做nasm。我所知道的是我在命令提示符中输入$ nasm -f elf64 -g -F dwarf filename.asm。

这是给我的代码,它是一个将整数转换为ascii值的函数。

itoa.asm

; itoa: convert a non-negative integer to ascii (text)
; itoa(buffer, n) -> # bytes written

global itoa

section .text

itoa:
            mov rax, rsi
            mov rsi, 0
            mov r10, 10

.loop:
            mov rdx, 0
            div r10
            add rdx, '0'
            mov [rdi + rsi], dl
            inc rsi
            cmp rax, 0
            jg .loop

            mov rdx, rdi
            lea rcx, [rdi + rsi -1]
            jmp .reversetest

.reverseloop:
            mov al, [rdx]
            mov ah, [rcx]
            mov [rcx], al
            mov [rdx], ah
            inc rdx
            dec rcx

.reversetest:
            cmp rdx, rcx
            jl .reverseloop

            mov rax, rsi
            ret

以下是说明

WRITEHEADER

编写汇编语言函数,将PPM文件的标题写入缓冲区。有关PPM文件的更多信息,请访问:

http://en.wikipedia.org/wiki/Netpbm_format 对于此函数,重要的部分是标题,其格式简单:

P3
xsize ysize
colormax

“P3”是硬编码的,表示使用中的格式(这称为魔术值)。 xsize和ysize值是以纯文本形式写出的整数,以像素为单位指示图像的大小。 colormax值表示每个颜色通道(红色,绿色和蓝色)的最大颜色值,并且为了我们的目的在255处进行硬编码。

对于1024×768图像,标题为:

P3
1024 768
255

字符串是什么:“P3 \ n1024 768 \ n255 \ n”

您的工作是将该标头写入缓冲区,并返回写入的字节数。

寄存器

功能不得干扰以下寄存器:

  • rbx,rbp,rsp,r12,r13,r14,r15

如果你需要使用其中的任何一个,你应该在函数开头将它们推入堆栈,并在返回之前将它们从堆栈中弹回。其他功能都将遵循这些相同的规则。

您的writeHeader实现将调用itoa。除了上面列表中的寄存器之外的任何寄存器都可能在itoa的调用中被销毁。由于您需要在调用中保留一些寄存器值,因此必须在进行调用之前将它们保存在某处。最简单的方法是选择一些调用者保存的寄存器(上面列出的寄存器)并使用它们。在函数开头,保存旧值:

push r13
push r14
push r15

然后你可以自由地在你的函数中使用这些寄存器,假设itoa将保留它们。在函数结束时,在返回之前,从堆栈中恢复这些寄存器:

pop r15
pop r14
pop r13

请注意,弹出窗口必须与推送发生的顺序相反。

这是我要编写函数的文件,文件中已经有一些代码已经给我了

writeheader.asm

; writeHeader(buffer, x, y) -> # bytes written
; writes a .ppm file header to the buffer, and returns the
; number of bytes written. The maximum color value is hard-coded
; at 255, but the x and y sizes can be any non-negative integers.
;
; example: writeHeader(buffer, 100, 50) writes
; "P3\n100 50\n255\n" to the buffer and returns 14.

global writeHeader
extern itoa

这是一个测试代码的c ++文件

test_writeheader.cpp

#include "gtest/gtest.h"

extern "C" int writeHeader(char *buffer, int x, int y);

TEST(writeHeader, all) {
    char buff[100];

    int n = writeHeader(buff, 0, 0);
    buff[n] = 0;
    EXPECT_EQ(strlen(buff), n);
    EXPECT_STREQ("P3\n0 0\n255\n", buff);

    n = writeHeader(buff, 1, 2);
    buff[n] = 0;
    EXPECT_EQ(strlen(buff), n);
    EXPECT_STREQ("P3\n1 2\n255\n", buff);

    n = writeHeader(buff, 1024, 768);
    buff[n] = 0;
    EXPECT_EQ(strlen(buff), n);
    EXPECT_STREQ("P3\n1024 768\n255\n", buff);

    n = writeHeader(buff, 2560, 1440);
    buff[n] = 0;
    EXPECT_EQ(strlen(buff), n);
    EXPECT_STREQ("P3\n2560 1440\n255\n", buff);
}

我知道我不应该要求人们编写我的代码,但是我被困住了,真的可以使用一些帮助。如果你更愿意写sudo代码来做如何做,我相信我可以找出其余部分。

0 个答案:

没有答案