我正在上课,我们用汇编语言编程。我们刚刚开始,所以我对此很陌生,并且很难跟进。我们使用的是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”
您的工作是将该标头写入缓冲区,并返回写入的字节数。
寄存器
功能不得干扰以下寄存器:
如果你需要使用其中的任何一个,你应该在函数开头将它们推入堆栈,并在返回之前将它们从堆栈中弹回。其他功能都将遵循这些相同的规则。
您的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代码来做如何做,我相信我可以找出其余部分。