Question: here my c code-#include batt.h //int set_batt_from_ports(batt_t *batt); // Uses the two global variables (ports) BATT_VOLTAGE_PORT and // BATT_STATUS_PORT to set the fields of the

here my c code-#include "batt.h"

//int set_batt_from_ports(batt_t *batt);

// Uses the two global variables (ports) BATT_VOLTAGE_PORT and

// BATT_STATUS_PORT to set the fields of the parameter 'batt'. If

// BATT_VOLTAGE_PORT is negative, then battery has been wired wrong;

// no fields of 'batt' are changed and 1 is returned to indicate an

// error. Otherwise, sets fields of batt based on reading the voltage

// value and converting to percent using the provided formula. Returns

// 0 on a successful execution with no errors. This function DOES NOT

// modify any global variables but may access global variables.

//

// CONSTRAINT: Avoids the use of the division operation as much as

// possible. Makes use of shift operations in place of division where

// possible.

//

// CONSTRAINT: Uses only integer operations. No floating point

// operations are used as the target machine does not have a FPU.

int set_batt_from_ports(batt_t *batt) {

if (BATT_VOLTAGE_PORT

return 1;

}

// voltage conversion

batt->mlvolts = BATT_VOLTAGE_PORT / 2;

// percent based on voltage range

if (batt->mlvolts

batt->percent = 0;

} else if (batt->mlvolts > 3800) {

batt->percent = 100;

} else {

batt->percent = (batt->mlvolts - 3000) / 8;

}

// clamp within range

if (batt->percent > 100) {

batt->percent = 100;

}

// determine mode bit

if (BATT_STATUS_PORT & (1

batt->mode = 1;

} else {

batt->mode = 2;

}

return 0;

}

//int set_display_from_batt(batt_t batt, int *display);

// Alters the bits of integer pointed to by 'display' to reflect the

// data in struct param 'batt'. Does not assume any specific bit

// pattern stored at 'display' and completely resets all bits in it on

// successfully completing. Selects either to show Percent (mode=1) or

// Volts (mode=2). If Volts are displayed, only displays 3 digits

// rounding the lowest digit up or down appropriate to the last digit.

// Calculates each digit to display changes bits at 'display' to show

// the volts/percent according to the pattern for each digit. Modifies

// additional bits to show a decimal place for volts and a 'V' or '%'

// indicator appropriate to the mode. In both modes, places bars in

// the level display as indicated by percentage cutoffs in provided

// diagrams. This function DOES NOT modify any global variables but

// may access global variables.

//

// ERRORS: Early in the function checks that the `mlvolts` field is

// positive and the `mode` field is either 1 or 2. If not, immediately

// returns 1 without changing the `display` parameter. (This error

// checking is new and was not presnet in the Project 2 version)

int set_display_from_batt(batt_t batt, int *display) {

// Set the display bits based on battery data.

int display_bits[11] = {

0b0111111, 0b0000110, 0b1011011, 0b1001111, 0b1100110,

0b1101101, 0b1111101, 0b0000111, 0b1111111, 0b1101111, 0

};

// Shows volts and percent .

int mv;

if (batt.mlvolts

mv = 0;

else

mv = batt.mlvolts;

if (batt.percent

batt.percent = 0;

int left_digit = 10, middle_digit = 10, right_digit = 10;

unsigned int disp = 0;

// volts mode

if (batt.mode == 2 && mv == 0 && batt.percent == 0) {

left_digit = 0; middle_digit = 0; right_digit = 0;

disp |= (1

} else if (batt.mode == 2) {

int r = (mv + 5) / 10;

left_digit = mv / 1000;

middle_digit = (mv / 100) % 10;

right_digit = r % 10;

disp |= (1

//percent mode

} else {

if (batt.percent > 100)

batt.percent = 100;

if (batt.percent == 100) {

left_digit = 1; middle_digit = 0; right_digit = 0;

} else if (batt.percent >= 10) {

middle_digit = batt.percent / 10;

right_digit = batt.percent % 10;

} else {

right_digit = batt.percent;

}

disp |= (1

}

// add level bars

disp |= (batt.percent > 89)

disp |= (batt.percent > 69)

disp |= (batt.percent > 49)

disp |= (batt.percent > 29)

disp |= (batt.percent > 4)

// add digits

disp |= (display_bits[left_digit]

disp |= (display_bits[middle_digit]

disp |= (display_bits[right_digit]

// pointed integer

*display = disp;

return 0;

}

//int batt_update();

// Called to update the battery meter display. Makes use of

// set_batt_from_ports() and set_display_from_batt() to access battery

// voltage sensor then set the display. Checks these functions and if

// they indicate an error, does NOT change the display. If functions

// succeed, modifies BATT_DISPLAY_PORT to show current battery level.

//

// CONSTRAINT: Does not allocate any heap memory as malloc() is NOT

// available on the target microcontroller. Uses stack and global

// memory only.

int batt_update() {

// local battery data

batt_t batt;

int result = set_batt_from_ports(&batt);

// read battery data from ports

if (result != 0) // check error

return 1;

// holds display bits

int display;

set_display_from_batt(batt, &display);

// output the new display to the hardware port

BATT_DISPLAY_PORT = display;

return 0;

}

and my assabmly verson-text .global set_batt_from_ports

## ENTRY POINT FOR REQUIRED FUNCTION set_batt_from_ports: movw BATT_VOLTAGE_PORT(%rip), %ax # # Loads 16-bit voltage reading into AX register cmp $0x0, %ax jl .FAIL_SET # fails if BATT_VOLTAGE_PORT is negative sarw $0x1, %ax # div by 2 movw %ax, (%rdi) # set mvolts field of batt struc cmp $0x0bb8, %ax # checks if the percentage is less than 0 jl .MIN_PERCENT cmp $0x0ed8, %ax # checks if the percentage is greater than 100 jg .MAX_PERCENT subw $0x0bb8, %ax sarw $0x3, %ax movb %al, 0x2(%rdi) # puts mvolts -3000 / 8 into percent field of batt struct jmp .AFTER_PERCENT

.MIN_PERCENT: movb $0x00, 0x2(%rdi) # puts 0 into percent field of batt struct jmp .AFTER_PERCENT .MAX_PERCENT: movb $0x64, 0x2(%rdi) # puts 100 into percent field of batt struct .AFTER_PERCENT: movb BATT_STATUS_PORT(%rip), %al andb $0x10, %al # masks all but bit 3 of BATT_STATUS_PORT cmpb $0x00, %al je .MODE_TWO movb $0x01, 0x3(%rdi) # puts mode into mode field of batt struct jmp .DONE_MODE .MODE_TWO: movb $0x02, 0x3(%rdi) .DONE_MODE: xor %eax, %eax ret .FAIL_SET: movl $0x1, %eax # returns a value of 1 ret

### Change to definint semi-global variables used with the next function ### via the '.data' directive .data

seven_segment_encoder: # Encodes decimal 0..9 and blank (10) .int 0b0111111 # 0 .int 0b0000110 # 1 .int 0b1011011 # 2 .int 0b1001111 # 3 .int 0b1100110 # 4 .int 0b1101101 # 5 .int 0b1111101 # 6 .int 0b0000111 # 7 .int 0b1111111 # 8 .int 0b1101111 # 9 .int 0b0000000 # blank (10)

## WARNING: Don't forget to switch back to .text as below ## Otherwise you may get weird permission errors when executing .text .global set_display_from_batt

### ENTRY POINT FOR REQUIRED FUNCTION ### int set_display_from_batt(batt_t batt, int *display) set_display_from_batt: push %rbx # save registers push %r12 push %r13 push %r14 push %r15 subq $8, %rsp # stack alignment xor %r10d, %r10d # clear display bits ## Extract mode (top byte) movl %edi, %r8d # copy batt andl $0xff000000, %r8d # mask top byte sarl $24, %r8d # shift down to mode (1=%, 2=V)

## Validate mode cmp $2, %r8d # compare to 2 je .MODE_OK # jump if 2 cmp $1, %r8d # compare to 1 je .MODE_OK # jump if 1 movl $1, %eax # return 1 (invalid) jmp .RETURN ## Check mlvolts > 0 .MODE_OK: movl %edi, %eax # copy batt shll $16, %eax # move mlvolts to top sarl $16, %eax # sign extend test %eax, %eax # test if > 0 jge .MLV_OK # ok if >= 0 movl $1, %eax # invalid jmp .RETURN ## Extract percent (bits 16-23) .MLV_OK: movl %edi, %r9d # copy batt andl $0x00ff0000, %r9d # mask percent sarl $16, %r9d # shift down to get percent ## Level bars (bits 24-28) movl %r9d, %eax # load percent cmpl $4, %eax # check >4 jle .NO_BAR0 movl $1, %ecx sall $24, %ecx # bit 24 orl %ecx, %r10d .NO_BAR0: movl %r9d, %eax cmpl $29, %eax # check >29 jle .NO_BAR1 movl $1, %ecx sall $25, %ecx # bit 25 orl %ecx, %r10d .NO_BAR1: movl %r9d, %eax cmpl $49, %eax # check >49 jle .NO_BAR2 movl $1, %ecx sall $26, %ecx # bit 26 orl %ecx, %r10d .NO_BAR2: movl %r9d, %eax cmpl $69, %eax # check >69 jle .NO_BAR3 movl $1, %ecx sall $27, %ecx # bit 27 orl %ecx, %r10d .NO_BAR3: movl %r9d, %eax cmpl $89, %eax # check >89 jle .NO_BAR4 movl $1, %ecx sall $28, %ecx # bit 28 orl %ecx, %r10d

## Mode indicator bits .NO_BAR4: cmp $2, %r8d # volts mode? jne .PERCENT_BITS movl $1, %eax sall $1, %eax # bit 1 orl %eax, %r10d sall $1, %eax # bit 2 orl %eax, %r10d jmp .AFTER_MODE_BITS .PERCENT_BITS: movl $1, %eax # bit 0 for percent orl %eax, %r10d .AFTER_MODE_BITS: cmp $2, %r8d # mode check again je .SHOW_VOLTS jmp .SHOW_PERCENT ## Voltage Mode (V) .SHOW_VOLTS: movl %edi, %r11d andl $0x0000ffff, %r11d # isolate mlvolts

movl %r11d, %eax xorl %edx, %edx movl $1000, %ecx divl %ecx movl %eax, %r12d # left digit = mv/1000

movl %r11d, %eax xorl %edx, %edx movl $100, %ecx divl %ecx xorl %edx, %edx movl $10, %ecx divl %ecx movl %edx, %r15d # middle = (mv/100)%10

movl %r11d, %eax addl $5, %eax # round xorl %edx, %edx movl $10, %ecx divl %ecx xorl %edx, %edx movl $10, %ecx divl %ecx movl %edx, %r9d # right = ((mv+5)/10)%10 leaq seven_segment_encoder(%rip), %rbx movl (%rbx,%r9,4), %eax sall $3, %eax orl %eax, %r10d movl (%rbx,%r15,4), %eax sall $10, %eax orl %eax, %r10d movl (%rbx,%r12,4), %eax sall $17, %eax orl %eax, %r10d jmp .END_NUMBERS ## Percent Mode (%) .SHOW_PERCENT: movl %edi, %r11d andl $0x00ff0000, %r11d sarl $16, %r11d # get percent

movl %r11d, %eax xorl %edx, %edx movl $100, %ecx divl %ecx movl %eax, %r12d # left = percent/100 movl $0, %r8d test %eax, %eax jne .LEFT_OK movl $10, %r12d # blank if zero movl $1, %r8d .LEFT_OK: movl %r11d, %eax xorl %edx, %edx movl $10, %ecx divl %ecx movl %edx, %r14d # right = % % 10 movl %eax, %eax xorl %edx, %edx movl $10, %ecx divl %ecx movl %edx, %r13d # middle = (%/10)%10

cmp $1, %r8d jne .MIDDLE_OK test %r13d, %r13d jne .MIDDLE_OK movl $10, %r13d # blank middle if left blank .MIDDLE_OK: leaq seven_segment_encoder(%rip), %rbx movl (%rbx,%r14,4), %eax sall $3, %eax orl %eax, %r10d movl (%rbx,%r13,4), %eax sall $10, %eax orl %eax, %r10d movl (%rbx,%r12,4), %eax sall $17, %eax orl %eax, %r10d ### Write result and return .END_NUMBERS: movl %r10d, (%rsi) # *display = disp xorl %eax, %eax # return 0 jmp .RETURN

.RETURN: addq $8, %rsp # restore stack pop %r15 pop %r14 pop %r13 pop %r12 pop %rbx ret # return

.text .global batt_update

## ENTRY POINT FOR REQUIRED FUNCTION batt_update: subq $0x10, %rsp leaq (%rsp), %rdi # rdi = &batt call set_batt_from_ports # returns result in eax cmp $0x0, %eax jne .FAIL # if nonzero, jump to fail movl 0(%rsp), %edi # load batt.mlvolts (2 bytes) into edi movzbl 2(%rsp), %esi # load batt.percent as byte ??? zero-extend to 32 bits shll $16, %esi # move into bits [23:16] orl %esi, %edi # combine with mlvolts movzbl 3(%rsp), %esi # load batt.mode byte shll $24, %esi # move into bits [31:24] orl %esi, %edi # combine all into edi leaq 8(%rsp), %rsi # rsi = &display call set_display_from_batt movl 8(%rsp), %eax # load display value movl %eax, BATT_DISPLAY_PORT(%rip) xor %eax, %eax # eax = 0 (return value) addq $0x10, %rsp # restore stack ret .FAIL: movl $1, %eax # return 1 addq $0x10, %rsp # restore stack ret

rewrite the assamly code with easy and simple verson

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Mathematics Questions!