Last Updated: 2024-10-30 Wed 09:35

CMSC216 Assembly Review Exercise

CODE DISTRIBUTION: hw-review-asm-code.zip

  • Download the code distribution every HW
  • See further setup instructions below

CHANGELOG:

Wed Oct 30 09:31:24 AM EDT 2024
The code pack was incorrectly named in the link: it should be hw-review-asm-code.zip; the link has been repaired for those who wish to download the codepack.

Table of Contents

1 Review Problem

On a recent practice exam, an assembly version of the following C function was created.

// setday_fun.c: sample function to convert to assembly
int DAYS_SINCE_1970;

typedef struct {
  int day;  int year;
} yearday_t;

int setday(yearday_t yd){
  int day = yd.day;
  int year = yd.year;
  if(day < 0 || year < 1970){
    DAYS_SINCE_1970 = -1;
    return 1;
  }

  int totaldays = day + (year - 1970)*365;
  DAYS_SINCE_1970 = totaldays;
  return 0;
}

This function was demonstrated in a main() function like the one below.

// setday_main2.c: a sample main() that calls setday()
#include <stdio.h>
#include <stdlib.h>

// global: days since 1/1/1970
extern int DAYS_SINCE_1970;

// struct containing date info
typedef struct {
  int day;  int year;
} yearday_t;
// Layout of yearday_t in memory and 
// as a packed register argument.
// 
// |       | Byte |   Byte | Packed |
// | Field | Size | Offset |   Bits |
// |-------+------+--------+--------|
// | day   | 4    |     +0 |   0-31 |
// | year  | 4    |     +4 |  32-63 |

int setday(yearday_t yd);

int main(int argc, char *argv[]){
  yearday_t yd2 = 
    { .day = 3, .year = 1972 };
  int ret = setday(yd2);
  printf("%3d days since 1970 (ret: %d)\n",
         DAYS_SINCE_1970, ret);
  // 733 days since 1970 (ret: 0)

  return 0;
}

When compiled and run together, the output looks like the following

>> cd review-asm-code
>> gcc setday_func.c setday_main2.c
>> ./a.out
733 days since 1970 (ret: 0)

A good exercise is to convert this main() into assembly as it requires setting up a packed struct argument to a function. There are two potnetial options for this:

  1. Place the struct in the stack and initialize its fields there, then load the struct into a register
  2. Directly place the struct in a register

Select one that seems right and complete the provided template version of an assembly version of main().

### TEMPLATE for setday_main2_asm.s ###
.data
FORMAT:
        .string "%3d days since 1970 (ret: %d)\n"

.text
.global main
main:
        ## grow the stack + align for function calls

        ## set up arg(s) and call setday function 

        call ???

        ## set up args and call printf@PLT function
        ## 3rd arg to printf: return value of setday
        ## 2nd arg to printf is DAYS_SINCE_1970 (global var)
        ## 1st arg to printf is FORMAT string address
        movl    $0,%eax         # requirement for printf and other var-arg functions
        call    printf@PLT

        ## restore the stack and return from main

After completing your code, compile and run it to see if it matches the same behavior as the C version.

SOLUTION


Web Accessibility
Author: Chris Kauffman (profk@umd.edu)
Date: 2024-10-30 Wed 09:35