|
CS456 - Systems Programming
| Displaying exercises/e5/solution/pyramid.s
%include "lib/lib.h"
extern puts, putc
SECTION .data
usage: db `Usage: pyramid <height>\n`,0
error: db `height must be positive.\n`,0
SECTION .text
atol: ;long atol(char *rsi) {
MOV rax, 0 ; int rax = 0, rbx = 10, r13;
MOV r13, 0
MOV rbx, 10
.loop CMP BYTE [rsi], 0
JE .done ; while(*rsi != '\0') {
CQO
MUL rbx ; rax *= rbx;
MOV r13b, BYTE [rsi]
SUB r13, '0' ; r13 = *rsi - '0';
ADD rax, r13 ; rax += r13;
INC rsi ; rsi++;
JMP .loop ; }
.done RET ; return rax;
global _start
_start:
mov rax, [rsp] ; if (argc < 2) {
cmp rax, 2
jge .getnum
mov rsi, usage
call puts ; printf("Usage: pyramid <height>\n");
mov rax, SYS_EXIT ; return 0;
mov rdi, 0
syscall ; }
.getnum:
mov rsi, [rsp+16]
call atol
mov r15, rax ; h(r15) = atol(argv[1]);
cmp r15, 0 ; if (h <= 0) {
jg .pyramid
mov rsi, error ; printf("height must be positive.\n");
call puts
mov rax, SYS_EXIT ; return 1;
mov rdi, 1
syscall ; }
.pyramid:
mov r14, r15
dec r14 ; s = h-1
mov r13, 1 ; a = 1
mov r12, 0 ; i = 0
.mainloop:
cmp r12, r15 ; while(i < h) {
je .done
mov rbx, 0 ; for(j = 0; j < s; j++) putchar(' ');
.loop1:
cmp rbx, r14
je .endloop1
mov rax, ' '
call putc
inc rbx
jmp .loop1
.endloop1:
mov rbx, 0 ; for(j = 0; j < a; j++) putchar(' ');
.loop2:
cmp rbx, r13
je .endloop2
mov rax, '*'
call putc
inc rbx
jmp .loop2
.endloop2:
mov rax, `\n` ; putchar('\n');
call putc
dec r14 ; s--;
add r13, 2 ; a += 2;
inc r12 ; i++;
jmp .mainloop
.done: ; }
mov rax, SYS_EXIT ; return 0;
mov rdi, 0
syscall
|